/** * * @param sources */ void EcuM_SetWakeupEvent(EcuM_WakeupSourceType sources) { EcuM_WakeupSourceType wkSource; DEBUG_ECUM_CALLIN_W_ARG("EcuM_SetWakeupEvent","0x%lx",(uint32)sources); /* @req 3.1.5/EcuM2826 The function exists */ /* @req 3.1.5/EcuM2171 */ /* @req 4.0.3|.1.5/ECUM2565 Validate at once for pre-defined sources */ wkSource = (ECUM_WKSOURCE_POWER | ECUM_WKSOURCE_RESET | ECUM_WKSOURCE_INTERNAL_RESET | ECUM_WKSOURCE_INTERNAL_WDG | ECUM_WKSOURCE_EXTERNAL_WDG); /* Sources that should be validated at once */ wkSource &= sources; if (wkSource != 0) { /* Move to validated */ EcuM_ValidateWakeupEvent(wkSource); } /* Don't add pre-defined source to PENDING */ sources ^= wkSource; /* @req 3.1.5/EcuM2867 */ #if ( ECUM_DEV_ERROR_DETECT == STD_ON ) /* Get user defined sources */ wkSource = EcuM_World.config->EcuMSleepModeConfig[EcuM_World.sleep_mode].EcuMWakeupSourceMask; /* Add always validated sources */ wkSource |= (ECUM_WKSOURCE_POWER|ECUM_WKSOURCE_RESET | ECUM_WKSOURCE_INTERNAL_RESET | ECUM_WKSOURCE_INTERNAL_WDG | ECUM_WKSOURCE_EXTERNAL_WDG); if( !((sources | wkSource) == wkSource)) { Det_ReportError(MODULE_ID_ECUM, 0, ECUM_VALIDATE_WAKEUP_EVENT_ID, ECUM_E_UNKNOWN_WAKEUP_SOURCE ); return; } #endif /* @req 3.1.5/EcuM1117 */ EcuM_World.wakeupEvents |= sources; /* @req 3.1.5/EcuM2707 @req 3.1.5/EcuM2709*/ EcuM_World.validationTimer = ECUM_VALIDATION_TIMEOUT / ECUM_MAIN_FUNCTION_PERIOD; }
void EcuM_MainFunction(void) { static uint32 pendingWkupMask = 0; static boolean validationOngoing = false; static uint32 validationMaxTime; if (!validationOngoing) { pendingWkupMask = EcuM_GetPendingWakeupEvents(); EcuM_StartWakeupSources(pendingWkupMask); EcuM_World.validationTimer = 0; /* Calculate the validation timing , if any*/ /* @req EcuM2494 */ /* @req EcuM2479 */ const EcuM_WakeupSourceConfigType *wkupCfgPtr; for (int i = 0; i < ECUM_WKSOURCE_USER_CNT; i++) { wkupCfgPtr = &EcuM_World.config->EcuMWakeupSourceConfig[i]; /* Can't validate something that is not pending */ if (pendingWkupMask & wkupCfgPtr->EcuMWakeupSourceId) { /* No validation timeout == ECUM_VALIDATION_TIMEOUT_ILL */ if (wkupCfgPtr->EcuMValidationTimeout != ECUM_VALIDATION_TIMEOUT_ILL) { /* Use one validation timeout, take the longest */ validationMaxTime = MAX( wkupCfgPtr->EcuMValidationTimeout / ECUM_MAIN_FUNCTION_PERIOD, validationMaxTime); EcuM_World.validationTimer = validationMaxTime; } else { /* Validate right away */ /* @req EcuM2976 */ EcuM_ValidateWakeupEvent(wkupCfgPtr->EcuMWakeupSourceId); } } } validationOngoing = true; } if (EcuM_World.validationTimer != 0) { /* * Call EcuM_CheckValidation() while all events have not been validated and * timeout have not expired. The call to EcuM_CheckValidation(..) triggers a call * to EcuM_ValidateWakeupEvent(..) from the driver when validated. */ /* Check validation for the events that do not match, ie not yet validated */ EcuM_CheckValidation(EcuM_GetValidatedWakeupEvents() ^ pendingWkupMask); /* !req EcuM2495*/ if (0 == (EcuM_GetValidatedWakeupEvents() ^ pendingWkupMask)) { /* All events have been validated */ validationOngoing = false; } } else { uint32 notValidatedMask = EcuM_GetValidatedWakeupEvents() ^ pendingWkupMask; /* Stop wakeupSources that are not validated */ if (notValidatedMask) { EcuM_StopWakeupSources(notValidatedMask); BswM_EcuM_CurrentWakeup((EcuM_WakeupSourceType)notValidatedMask, ECUM_WKSTATUS_EXPIRED); } validationOngoing = false; } /* @req 3.1.5/EcuM2710 */ if (EcuM_World.validationTimer) { EcuM_World.validationTimer--; } }
//----- MAIN ----------------------------------------------------------------------------------------------------------------- void EcuM_MainFunction(void) { EcuM_WakeupSourceType wMask=0; #if defined(USE_LDEBUG_PRINTF) static uint32 validationMask; #endif static uint32 validationMaxTime; static uint32 pendingWkupMask = 0; #if (ECUM_AR_VERSION < 40000) VALIDATE_NO_RV(EcuM_World.initiated, ECUM_MAINFUNCTION_ID, ECUM_E_UNINIT); #else /* @req EcuMf0029 */ if (!EcuM_World.initiated) { return; } #endif #if defined(USE_LDEBUG_PRINTF) { static EcuM_StateType oldEcuMState = 0xff; if( oldEcuMState != EcuM_World.current_state) { DEBUG_ECUM_STATE(EcuM_World.current_state); oldEcuMState = EcuM_World.current_state; } } #endif switch (EcuM_World.current_state) { case ECUM_STATE_APP_RUN: /* RUN II state */ in_state_appRun(); break; case ECUM_STATE_APP_POST_RUN: /* RUN III state */ in_state_appPostRun(); break; case ECUM_STATE_PREP_SHUTDOWN: in_state_prepShutdown(); break; case ECUM_STATE_GO_OFF_ONE: in_state_goOffOne(); break; case ECUM_STATE_GO_SLEEP: /* 4 cases: * 1. Wait for the NvM_WriteAll() - Stay in state * 2. Timeout on NvM_WriteAll() - go to ECUM_STATE_SLEEP (Scheduler is locked) * 3. NvM_WriteAll() is done - go to ECUM_STATE_SLEEP (Scheduler is locked) * 4. Run request - Call NvM_CancelAll() and go to ECUM_STATE_WAKEUP_ONE. */ in_state_goSleep(); if( EcuM_World.current_state != ECUM_STATE_SLEEP ) { break; } /* Flow Through, Scheduler is Locked */ //lint -fallthrough MISRA 2004 Rule 15.2 case ECUM_STATE_SLEEP: in_state_sleep(); /* Flow Through, Scheduler is Locked */ //lint -fallthrough MISRA 2004 Rule 15.2 case ECUM_STATE_WAKEUP_ONE: { DEBUG_ECUM_STATE(EcuM_World.current_state); /*@req EcuMF2975 */ Mcu_SetMode(EcuM_World.config->EcuMNormalMcuMode); wMask = EcuM_GetPendingWakeupEvents(); DEBUG_ECUM_CALLOUT_W_ARG("EcuM_DisableWakeupSources", "0x%lx", (uint32) wMask); EcuM_DisableWakeupSources(wMask); /* @req EcuM2562 */ /* @req EcuMf2562 */ EcuM_AL_DriverRestart(EcuM_World.config); EcuM_World.killAllRequest = false; /* Enable run request again */ (void)ReleaseResource(RES_SCHEDULER); #if defined(USE_LDEBUG_PRINTF) validationMask = 0; #endif validationMaxTime = 0; const EcuM_WakeupSourceConfigType *wkupCfgPtr; SetCurrentState(ECUM_STATE_WAKEUP_VALIDATION); /*-------------- ECUM_STATE_WAKEUP_VALIDATION -------------------- */ DEBUG_ECUM_CALLOUT(ECUM_STR "EcuM_GetPendingWakeupEvents"); pendingWkupMask = EcuM_GetPendingWakeupEvents(); DEBUG_ECUM_CALLOUT_W_ARG("EcuM_StartWakeupSources", "0x%lx",(uint32) pendingWkupMask); EcuM_StartWakeupSources(pendingWkupMask); EcuM_World.validationTimer = 0; /* Calculate the validation timing , if any*/ /* @req EcuMf2494 */ /* @req EcuM2479 */ /* @req EcuMf2479 */ for (int i = 0; i < ECUM_WKSOURCE_USER_CNT; i++) { wkupCfgPtr = &EcuM_World.config->EcuMWakeupSourceConfig[i]; /* Can't validate something that is not pending */ if (wMask & wkupCfgPtr->EcuMWakeupSourceId) { /* No validation timeout == ECUM_VALIDATION_TIMEOUT_ILL */ if ((wkupCfgPtr->EcuMValidationTimeout != ECUM_VALIDATION_TIMEOUT_ILL) && (wMask & wkupCfgPtr->EcuMWakeupSourceId)) { /* Build a mask with the sources that need validation */ #if defined(USE_LDEBUG_PRINTF) validationMask |= wkupCfgPtr->EcuMWakeupSourceId; #endif /* Use one validation timeout, take the longest */ validationMaxTime = MAX( wkupCfgPtr->EcuMValidationTimeout / ECUM_MAIN_FUNCTION_PERIOD, validationMaxTime); EcuM_World.validationTimer = validationMaxTime; } else { LDEBUG_PRINTF(ECUM_STR "No Validation for :0x%lx (EcuM_ValidateWakeupEvent() called)\n", (uint32) wkupCfgPtr->EcuMWakeupSourceId); /* Validate right away */ /* @req EcuM2976 */ /* @req EcuMf2976 */ EcuM_ValidateWakeupEvent(wkupCfgPtr->EcuMWakeupSourceId); } } } break; } case ECUM_STATE_WAKEUP_VALIDATION: { /* !req 3.1.5/EcuM2566 */ boolean done = 0; if (EcuM_World.validationTimer != 0) { /* * Call EcuM_CheckValidation() while all events have not been validated and * timeout have not expired. The call to EcuM_CheckValidation(..) triggers a call * to EcuM_ValidateWakeupEvent(..) from the driver when validated. */ /* Check validation for the events that do not match, ie not yet validated */ DEBUG_ECUM_CALLOUT_W_ARG( "EcuM_CheckValidation", "0x%lx", (uint32)(EcuM_GetValidatedWakeupEvents() ^ pendingWkupMask)); EcuM_CheckValidation( EcuM_GetValidatedWakeupEvents() ^ pendingWkupMask); /* !req EcuMf2495*/ if (0 == (EcuM_GetValidatedWakeupEvents() ^ pendingWkupMask)) { /* All events have been validated */ done = 1; } else { LDEBUG_PRINTF( ECUM_STR " Awaiting validation for mask: pending=%lx, expected=%lx\n", pendingWkupMask, validationMask); LDEBUG_PRINTF(ECUM_STR " Validation Timer : %lu\n", EcuM_World.validationTimer); } } else { uint32 notValidatedMask = EcuM_GetValidatedWakeupEvents() ^ pendingWkupMask; /* Stop wakeupSources that are not validated */ if (notValidatedMask) { DEBUG_ECUM_CALLOUT_W_ARG("EcuM_StopWakeupSources", "0x%lx", (uint32) notValidatedMask); EcuM_StopWakeupSources(notValidatedMask); #if defined(USE_BSWM) BswM_EcuM_CurrentWakeup(notValidatedMask, ECUM_WKSTATUS_EXPIRED); #endif } done = 1; } /* @req 3.1.5/EcuM2710 */ if (EcuM_World.validationTimer) { EcuM_World.validationTimer--; } if (done) { #if defined(USE_COMM) const EcuM_WakeupSourceConfigType *wkupCfgPtr; uint32 validated = EcuM_GetValidatedWakeupEvents(); for(int i=0;i<ECUM_WKSOURCE_USER_CNT;i++) { wkupCfgPtr = &EcuM_World.config->EcuMWakeupSourceConfig[i]; /* Call wakeup indication for all validated events with a channel assigned */ if ( (wkupCfgPtr->EcuMComMChannel != ECUM_COMM_CHANNEL_ILL) && wkupCfgPtr->EcuMWakeupSourceId & validated ) { ComM_EcuM_WakeUpIndication(wkupCfgPtr->EcuMComMChannel); } } #endif SetCurrentState(ECUM_STATE_WAKEUP_REACTION); } break; } case ECUM_STATE_WAKEUP_REACTION: { /* * At this stage we want to know how to react to the wakeup, e.g. go * back to RUN or SHUTDOWN, etc. */ EcuM_WakeupReactionType wReaction; wMask = EcuM_GetValidatedWakeupEvents(); LDEBUG_PRINTF(ECUM_STR "EcuM_GetValidatedWakeupEvents() : %x\n", wMask); /* NOTE: We have skipped the TTII timer here */ /* If the wakeup mask here is != 0 we have a validated wakeup event -> * go back to RUN */ wReaction = (0 == wMask) ? ECUM_WKACT_SHUTDOWN : ECUM_WKACT_RUN; wReaction = EcuM_OnWakeupReaction(wReaction); LDEBUG_PRINTF(ECUM_STR "Wakeup Reaction: %s\n", GetWakeupReactionAsString(wReaction)); if (wReaction == ECUM_WKACT_RUN) { /* @req EcuMf2568 */ SetCurrentState(ECUM_STATE_WAKEUP_TWO); } else { /* From figure 28 it seems that we should go to SHUTDOWN/GO SLEEP) again from wakeup * not going up to RUN/RUN II state again. */ /* @req EcuMf2711 */ /* @req EcuMf2567 */ SetCurrentState(ECUM_STATE_GO_SLEEP); } break; } case ECUM_STATE_WAKEUP_TWO: #if defined(USE_DEM) Dem_Init(); #endif EcuM_enter_run_mode(); // SetCurrentState(ECUM_STATE_APP_RUN); break; default: //IMPROVEMENT: Report error. break; } }