[AutoSar]状态管理(五)Dcm与BswM、EcuM的复位实现

发布时间:2023年12月22日


??

关键词

嵌入式、C语言、autosar、EcuM、Rte、BswM

平台说明

项目Value
OSautosar OS
autosar厂商vector
芯片厂商TI
编程语言C,C++
编译器HighTec (GCC)

在这里插入图片描述

前言

本文档主要描述了如何实现Dcm实现复位的流程(hardwareReset)

一、总体流程

二、配置

在这里插入图片描述

2.1 DCM and DEM

在DcmDsdService中配置好复位服务

在这里插入图片描述

2.2 BSWM

2.2.1 Mode Notifaication Port

DcmEcuReset是基于Dcm的标准接口,如果没有自动生成请手动创建。

在这里插入图片描述

2.2.2 Rules

创建对应的expression、action、actionlist和rules用于当诊断触发时的操作。

在这里插入图片描述

2.3 service port

2.3.1 做好DCM–>BSWM 和DCM -->SWC_Diag 的server port mapping

在这里插入图片描述

2.3.2 做好BSWM ESH_ModeNotification 的server port mapping

在这里插入图片描述

2.4 SWC 中mapping DcmEcuReset port

后续SWC_Diag runnable 操作和触发是模式进入决定还是其他由开发者决定。

在这里插入图片描述

三、code

3.1 BswM

3.1.1判定从Dcm传过来的复位模式设定请求

BSWM_LOCAL FUNC(BswM_HandleType, BSWM_CODE) BswM_Rule_BswMRule_DcmEcuResetHard(BswM_PCPartitionConfigIdxOfPartitionIdentifiersType partitionIdx)
{
  BswM_HandleType retVal = BSWM_NO_ACTIONLIST(partitionIdx);
  /* Evaluate logical expression LE_BswMRule_DcmEcuResetHard. */
  if(BswM_Mode_Notification_DcmEcuReset_DcmEcuReset == RTE_MODE_DcmEcuReset_HARD)
  {
    if( BswM_GetRuleStates(BSWM_ID_RULE_BswMRule_DcmEcuResetHard, partitionIdx) != BSWM_TRUE ) /* COV_BSWM_TRIGGEREDRULEEXECUTION */
    {
      BswM_UpdateRuleStates(BSWM_ID_RULE_BswMRule_DcmEcuResetHard, BSWM_TRUE, partitionIdx);
      /* Return triggered action list BswM_ActionList_AL_DcmEcuResetHardActions. */
      retVal = BSWM_ID_AL_AL_DcmEcuResetHardActions;
    }
  }
  else
  {
    BswM_UpdateRuleStates(BSWM_ID_RULE_BswMRule_DcmEcuResetHard, BSWM_FALSE, partitionIdx);
    /* No false action list configured. */
  }
  BSWM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */
  return retVal;
}

3.1.2 执行设置下电模式和操作

BSWM_LOCAL FUNC(Std_ReturnType, BSWM_CODE) BswM_ActionList_AL_DcmEcuResetHardActions(BswM_PCPartitionConfigIdxOfPartitionIdentifiersType partitionIdx)
{
  /*lint -save -e534 *//* PRQA S 3109, 3200 1 */ /* MD_MSR_14.3, MD_BSWM_3200 */
  Dem_Shutdown();
  /*lint -restore */
  BswM_UpdateTimer(partitionIdx, BSWM_TMR_ESH_NvM_WriteAllTimer, 6000u);
  /*lint -save -e534 *//* PRQA S 3109, 3200 1 */ /* MD_MSR_14.3, MD_BSWM_3200 */
  NvM_WriteAll();
  /*lint -restore */
  (void)EcuM_SelectShutdownTarget(ECUM_STATE_RESET, EcuMConf_EcuMResetMode_ECUM_RESET_IO);
  BSWM_DUMMY_STATEMENT(partitionIdx); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */
  return E_OK;
}/* PRQA S 6010, 6030, 6050 */ /* MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STCAL */

3.2 Dcm

调用0x11服务触发。
/*! Service 0x11 sub-service properties table  */
CONST(Dcm_CfgSvc11SubFuncInfoType, DCM_CONST) Dcm_CfgSvc11SubFuncInfo[4]=
{
   { Dcm_Service11_01Processor} /* SF: 0x01 */
  ,{ Dcm_Service11_03Processor} /* SF: 0x03 */
  ,{ Dcm_Service11_04Processor} /* SF: 0x04 */
  ,{ Dcm_Service11_05Processor} /* SF: 0x05 */
};

3.3 Rte

数据传递:Dcm – > BswM,Dcm --> SWC_diag, BswM – >EcuM

FUNC(Dcm_EcuResetType, RTE_CODE) Rte_Mode_BswM_Notification_DcmEcuReset_DcmEcuReset(void) /* PRQA S 3408 */ /* MD_Rte_3408 */
{
  Dcm_EcuResetType curMode;
  if (Rte_AckFlags.Rte_ModeSwitchAck_Dcm_DcmEcuReset_DcmEcuReset_Ack == 0U)
  {
    curMode = RTE_TRANSITION_BswM_DcmEcuReset;
  }
  else
  {
    curMode = Rte_ModeMachine_Dcm_DcmEcuReset_DcmEcuReset;
  }
  return curMode;
}

FUNC(Std_ReturnType, RTE_CODE) Rte_Switch_Dcm_DcmEcuReset_DcmEcuReset(Dcm_EcuResetType nextMode) /* PRQA S 1505 */ /* MD_MSR_Rule8.7 */
{
  Std_ReturnType ret = RTE_E_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */

  uint8 internalIndexNextMode = Rte_GetInternalModeIndex_Dcm_DcmEcuReset(nextMode);
  uint8 internalIndexCurrentMode;
  Dcm_EcuResetType currentMode;
  SuspendOSInterrupts();
  currentMode = Rte_ModeMachine_Dcm_DcmEcuReset_DcmEcuReset;
  internalIndexCurrentMode = Rte_GetInternalModeIndex_Dcm_DcmEcuReset(currentMode);
  if (internalIndexNextMode >= 7U)
  {
    ResumeOSInterrupts();
    Rte_CallDetReportError(RTE_SWITCH_SERVICE_ID, RTE_E_DET_MODEARGUMENT);
    ret = RTE_E_LIMIT;
  }
  else if (Rte_AckFlags.Rte_ModeSwitchAck_Dcm_DcmEcuReset_DcmEcuReset_Ack == 0U)
  {
    ret = RTE_E_LIMIT;
    ResumeOSInterrupts();
  }
  else if (internalIndexCurrentMode >= 7U)
  {
    ResumeOSInterrupts();
    Rte_CallDetReportError(RTE_SWITCH_SERVICE_ID, RTE_E_DET_MODESTATE);
    ret = RTE_E_LIMIT;
  }
  else
  {
    Rte_EventMaskType ModeSwitchEventMask;

    ModeSwitchEventMask = Rte_GetModeEntryEventMask_Dcm_DcmEcuReset_DcmEcuReset(internalIndexNextMode); /* PRQA S 2986 */ /* MD_Rte_2986 */

    if (ModeSwitchEventMask != (Rte_EventMaskType)0)
    {
      ret = Rte_IocSend_Rte_M_Dcm_DcmEcuReset_DcmEcuReset(nextMode);

      Rte_AckFlags.Rte_ModeSwitchAck_Dcm_DcmEcuReset_DcmEcuReset_Ack = 0U;
      ResumeOSInterrupts();

      (void)ActivateTask(Mode_Task); /* PRQA S 3417 */ /* MD_Rte_Os */
    }
    else
    {
      Rte_ModeMachine_Dcm_DcmEcuReset_DcmEcuReset = nextMode;
      Rte_AckFlags.Rte_ModeSwitchAck_Dcm_DcmEcuReset_DcmEcuReset_Ack = 1U;
      ResumeOSInterrupts();
    }
  }

  return ret;
} /* PRQA S 6010, 6030, 6050, 6080 */ /* MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STCAL, MD_MSR_STMIF */
FUNC(Dcm_EcuResetType, RTE_CODE) Rte_Mode_BswM_Notification_DcmEcuReset_DcmEcuReset(void) /* PRQA S 3408 */ /* MD_Rte_3408 */
{
  Dcm_EcuResetType curMode;
  curMode = Rte_ModeMachine_Dcm_DcmEcuReset_DcmEcuReset;
  return curMode;
}

3.4 EcuM

设置下电和复位模式

FUNC(Std_ReturnType, ECUM_CODE) EcuM_SelectShutdownTarget(VAR(EcuM_StateType, AUTOMATIC) targetState,
VAR(EcuM_ModeType, AUTOMATIC) resetSleepMode)
{
  /* ----- Local Variables ---------------------------------------------- */
  uint8 errorId = ECUM_E_NO_ERROR;
  Std_ReturnType retval;

  /* ----- Development Error Checks ------------------------------------- */
  /* #21 Check the current state of the EcuM. */
#if (ECUM_DEV_ERROR_DETECT == STD_ON)
  if ((EcuM_GetModuleState() < ECUM_STATE_STARTUP_TWO) || (EcuM_GetModuleState() > ECUM_STATE_APP_RUN))
  {
    errorId = ECUM_E_MODULE_NOT_IN_RUN_STATE;
    retval = E_NOT_OK;
  }
  else
  /* #22 Check if the parameters targetState and resetSleepMode are in a valid range.  */
  /* if (STATE == RESET AND ResetMode in Range) OR
   *     STATE == SLEEP AND SleepMode in Range) OR
   *     STATE == OFF)
   */
#endif
  if (
      /* Check for a valid state parameter */
      ((targetState != (EcuM_StateType) ECUM_STATE_OFF) && (targetState != (EcuM_StateType) ECUM_STATE_RESET)
          && (targetState != (EcuM_StateType) ECUM_STATE_SLEEP))
#if(ECUM_RESETMODECOUNT != 0u)
      ||
      /* Check for a valid reset mode parameter */
      ((targetState == (EcuM_StateType) ECUM_STATE_RESET) && (resetSleepMode >= ECUM_RESETMODECOUNT))
#endif
#if(ECUM_SLEEPMODELIST == STD_ON)
      ||
      /* Check for a valid sleep mode parameter */
      ((targetState == (EcuM_StateType) ECUM_STATE_SLEEP) && (resetSleepMode >= EcuM_GetSizeOfSleepModeList()))
# if(ECUM_VALIDOFSLEEPMODELIST == STD_ON)
      ||
      /* Check if this sleep mode is active in this variant */
      (!EcuM_IsValidOfSleepModeList(resetSleepMode))
# endif
#endif
  )
  {
    errorId = ECUM_E_STATE_PAR_OUT_OF_RANGE;
    retval = E_NOT_OK;
  }
  else
  {
    /* ----- Implementation ----------------------------------------------- */
    if (targetState == ECUM_STATE_OFF)
    {
      /* #30 Set the state of the current shutdown target. */
      /* #31 In case of ECUM_STATE_OFF ignore the resetSleepMode parameter and set the current shutdown mode to 0. */
      EcuM_InternalSetShutdownTargetAndMode(targetState, 0u);
    }
    else
    {
      /* #30 Set the state of the current shutdown target. */
      /* #32 In case of ECUM_STATE_SLEEP / ECUM_STATE_RESET set the current shutdown mode to parameters value. */
      EcuM_InternalSetShutdownTargetAndMode(targetState, resetSleepMode);
    }

    retval = E_OK;
  }

  /* ----- Development Error Report --------------------------------------- */
#if(ECUM_DEV_ERROR_REPORT == STD_ON)
  if (errorId != ECUM_E_NO_ERROR)
  {
    EcuM_Det_ReportError(ECUM_SID_SELECT_SHUTDOWN_TARGET, errorId);
  }
#else
  ECUM_DUMMY_STATEMENT(errorId); /* PRQA S 1338, 2983, 3112 */ /* MD_MSR_DummyStmt */
#endif

  return retval;
}
FUNC(Std_ReturnType, ECUM_CODE) EcuM_GoToSelectedShutdownTarget(void)
{
  /* ----- Local Variables ---------------------------------------------- */
  Std_ReturnType retVal;
# if (ECUM_SLEEPMODELIST == STD_ON)
  EcuM_StateType localShutdownTarget;
  uint8 localShutdownMode;

  /* ----- Implementation ----------------------------------------------- */
  EcuM_InternalGetShutdownTargetAndMode(&localShutdownTarget, &localShutdownMode); /* SBSW_ECUM_POINTER_TO_LOCAL_VARIABLES */
  /* Check if the current shutdown target is set to Sleep, Reset or Off. */
  if (localShutdownTarget == ECUM_STATE_SLEEP)
  {
#  if (ECUM_POLLINGOFSLEEPMODELIST == STD_ON)
    /*  In case of Sleep differ if the current sleepmode needs polling or not. */
    if (EcuM_IsPollingOfSleepModeList(localShutdownMode))
    {
      /* In case the sleepmode needs polling, call the corresponding EcuM API. */
      retVal = EcuM_GoPoll();
    }
    else
#  endif
    {
      /* In case the sleepmode does not need polling, call the corresponding EcuM API. */
      retVal = EcuM_GoHalt();
    }
  }
  else
# endif
  {
    /* In case of Off / Reset, call the corresponding EcuM API. */
    retVal = EcuM_GoDown( ECUM_MODULE_ID);
  }

  return retVal;
}
#endif

文章来源:https://blog.csdn.net/weixin_42447823/article/details/135161873
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。