[Davinci Configurator 配置] 实现功能寻址不响应、关闭抑制肯定响应、NRC否定响应

背景

在DCM开发过程中经常会遇到如下功能需求:

(1)某个UDS诊断服务不支持功能寻址的情况下,ECU接收到功能寻址的该UDS诊断服务,如何实现不响应该诊断服务。

        举例:2E服务不支持功能寻址,ECU接收到2E服务请求,则不响应

(2)某个UDS诊断服务不支持抑制肯定响应的情况下,ECU接收到带有抑制肯定响应的SID诊断服务,如何实现上报否定响应NRC12。

        举例:19服务不支持抑制肯定响应,ECU接收到19 8x xx请求,则响应NRC12

(3)如何实现ECU上报某些UDS诊断服务的NRC22否定响应。

        举例:11服务需要NRC22条件(车速小于3km/h)检测,当车速大于3km/h时ECU接收到11 01请求,则响应NRC22

配置教程

Davinci Configurator Pro配置工具预留两个通知功能(manufacturer notification和supplier notification),可根据不同需求选择相应的功能,这边我们选择的是supplier notification。该功能是在DCM模块接收到诊断服务后会先调用相应的接口执行一些逻辑判定,若判定为成功进行下一步诊断逻辑,否则直接返回相应的NRC。

1.使能supplier notification功能

如下图所示,在Dcm-->DcmConfigSet-->DcmGeneral模块中,勾选DcmRequestSupplierNotificationEnabled功能。

2.创建Supplier notification容器

在/MICROSAR/Dcm/DcmConfigSet/DcmDsl/DcmDslServiceRequestSupplierNotification模块中,右击选择“create xxx container”。

3.创建Notification Indication 和Notification Confirmation函数

如下图所示,点击步骤2中生成的容器,填写Notification Indication 和Notification Confirmation函数名。

4.生成DCM代码

如下图所示,点击“generate”图标,选择“DCM”模块,点击“generate”即可生成代码。到这里Davinci 配置就已经完成了,接下来我们手动实现相应的功能即可。

5.查看生成代码

我们先来初略的查看下Davinci cfg工具生成的代码,对比代码可以看到,在Dcm_Lcfg.c中定义了一个Dcm_CfgDiagSysNotificationInfo结构体数组,包含两个函数(即步骤3中创建的函数名)。同时在Dcm_Lcfg.h文件中还定义这两个函数的参数和返回值。

/*! System supplier notification functions */
CONST(Dcm_CfgDiagNotificationInfoType, DCM_CONST) Dcm_CfgDiagSysNotificationInfo[2]=
{
   { ServiceRequestNotification_ConditionCheck_Indication,ServiceRequestNotification_Confirmation}
  ,{ NULL_PTR,NULL_PTR}
};
/***********************************************************************************************************************
 *  ServiceRequestNotification_ConditionCheck_Indication()
***********************************************************************************************************************/
/*! \brief         Performs supplier specific validations on a diagnostic service request.
 *  \details       This function is a request from the DCM to the application to validate the received diagnostic
 *                 service, additionally to the DCM internal validation.
 *  \param[in]     SID                         Contains the diagnostic service Id
 *  \param[in]     RequestData                 Points to the request data. Points behind the service Id byte
 *  \param[in]     DataSize                    Specifies the requested data length (without the SID byte)
 *  \param[in]     ReqType                     Specifies the diagnostic request type:
 *                                             0 - physical request
 *                                             1 - functional request
 *  \param[in]     SourceAddress               Contains the diagnostic client source address
 *  \param[out]    ErrorCode                   NRC to be sent in the negative response in case of failure (E_NOT_OK)
 *  \return        E_OK                        The operation is finished
 *  \return        DCM_E_REQUEST_NOT_ACCEPTED  The diagnostic service shall not be processed.
 *                                             No response will be sent
 *  \return        E_NOT_OK                    The operation has failed
 *                                             A concrete NRC shall be set, otherwise the DCM sends NRC 0x22
 *  \context       TASK
 *  \reentrant     FALSE
 *  \synchronous   TRUE
 *  \pre           -
***********************************************************************************************************************/
FUNC(Std_ReturnType, DCM_CALLOUT_CODE) ServiceRequestNotification_ConditionCheck_Indication(uint8 SID, P2CONST(uint8, AUTOMATIC, DCM_VAR_NOINIT) RequestData, uint16 DataSize, uint8 ReqType, uint16 SourceAddress, P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, DCM_VAR_NOINIT) ErrorCode);
/***********************************************************************************************************************
 *  ServiceRequestNotification_Confirmation()
***********************************************************************************************************************/
/*! \brief         Finishes supplier specific actions on a diagnostic service request.
 *  \details       This function is a notification from the DCM to the application that a diagnostic service processing
 *                 is finished.
 *  \param[in]     SID                 Contains the diagnostic service Id
 *  \param[in]     ReqType             Specifies the diagnostic request type:
 *                                     0 - physical request
 *                                     1 - functional request
 *  \param[in]     SourceAddress       Contains the diagnostic client source address
 *  \param[in]     ConfirmationStatus  Contains the response transmission resp. diagnostic response type
 *  \return        E_OK                The operation is finished
 *  \return        E_NOT_OK            The operation has failed. Has no effect on DCM.
 *  \context       TASK
 *  \reentrant     FALSE
 *  \synchronous   TRUE
 *  \pre           -
***********************************************************************************************************************/
FUNC(Std_ReturnType, DCM_CALLOUT_CODE) ServiceRequestNotification_Confirmation(uint8 SID, uint8 ReqType, uint16 SourceAddress, Dcm_ConfirmationStatusType ConfirmationStatus);

6.实现Notification Indication 和Notification Confirmation函数

根据上面三个功能需求,我们分别对2E/19/11服务进行相应的逻辑处理。

在2E服务中,若接收到功能寻址的指令,则不响应请求。

在19服务中,若SID的bit7为1,则响应NRC12。

在11服务中,先获取当前车速,判定车速是否满足要求,若不满足,则返回NRC22

#define DIA_NRC22_CONDITION_VEHSPEED_LIMIT  (3.0f)
/***********************************************************************************************************************
 *  ServiceRequestNotification_ConditionCheck_Indication()
***********************************************************************************************************************/
/*! \brief         Performs supplier specific validations on a diagnostic service request.
 *  \details       This function is a request from the DCM to the application to validate the received diagnostic
 *                 service, additionally to the DCM internal validation.
 *  \param[in]     SID                         Contains the diagnostic service Id
 *  \param[in]     RequestData                 Points to the request data. Points behind the service Id byte
 *  \param[in]     DataSize                    Specifies the requested data length (without the SID byte)
 *  \param[in]     ReqType                     Specifies the diagnostic request type:
 *                                             0 - physical request
 *                                             1 - functional request
 *  \param[in]     SourceAddress               Contains the diagnostic client source address
 *  \param[out]    ErrorCode                   NRC to be sent in the negative response in case of failure (E_NOT_OK)
 *  \return        E_OK                        The operation is finished
 *  \return        DCM_E_REQUEST_NOT_ACCEPTED  The diagnostic service shall not be processed.
 *                                             No response will be sent
 *  \return        E_NOT_OK                    The operation has failed
 *                                             A concrete NRC shall be set, otherwise the DCM sends NRC 0x22
 *  \context       TASK
 *  \reentrant     FALSE
 *  \synchronous   TRUE
 *  \pre           -
***********************************************************************************************************************/
FUNC(Std_ReturnType, DCM_CALLOUT_CODE) ServiceRequestNotification_ConditionCheck_Indication(uint8 SID, P2CONST(uint8, AUTOMATIC, DCM_VAR_NOINIT) RequestData, uint16 DataSize, uint8 ReqType, uint16 SourceAddress, P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, DCM_VAR_NOINIT) ErrorCode)
{
    Std_ReturnType l_DcmReturn_e = DCM_E_OK;
    vfc::float32_t l_vehicleVelocity = 0;
    valin::EQualifierVehicleVelocity l_vehicleVelocityVaild = valin::EQualifierVehicleVelocity::Q_VEHICLE_VELOCITY_INVALID;
    valin::CValInOutputPf l_ValInResponse;

    if(true == ov_dia::Cov_diaRunnable::ov_dia_getInstance()->updateValInResponse(l_ValInResponse))
    {
        l_vehicleVelocity = vfc::abs(l_ValInResponse.m_pfOdometry.m_vehicleVelocityDisplay.value());
        l_vehicleVelocityVaild = l_ValInResponse.m_pfOdometry.m_qualifierVehicleVelocity;
    }

    switch (SID)
    {
        case 0x10:
            if(((*RequestData)&0x7F) == 0x02)
            {
                if(ReqType == DCM_FUNCTIONAL_REQUEST)
                {
                    l_DcmReturn_e = DCM_E_REQUEST_NOT_ACCEPTED;
                }
                else
                {
                    if((l_vehicleVelocityVaild == valin::EQualifierVehicleVelocity::Q_VEHICLE_VELOCITY_VALID)&& \
                        (l_vehicleVelocity > DIA_NRC22_CONDITION_VEHSPEED_LIMIT))
                    {
                        *ErrorCode = DCM_E_CONDITIONSNOTCORRECT;
                        l_DcmReturn_e = DCM_E_NOT_OK;
                    }
                }
            }
            break;
        
        case 0x11:
        case 0x14: 
        case 0x28:           
        case 0x85:
            if((l_vehicleVelocityVaild == valin::EQualifierVehicleVelocity::Q_VEHICLE_VELOCITY_VALID)&& \
                (l_vehicleVelocity > DIA_NRC22_CONDITION_VEHSPEED_LIMIT))
            {
                *ErrorCode = DCM_E_CONDITIONSNOTCORRECT;
                l_DcmReturn_e = DCM_E_NOT_OK;
            }
            break;

        case 0x19:
            if(((*RequestData)&0x80) != 0x00)
            {
                *ErrorCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;
                l_DcmReturn_e = DCM_E_NOT_OK;
            }
            break;

        case 0x2E:
        case 0x34:
        case 0x36:
        case 0x37:        
            if(ReqType == DCM_FUNCTIONAL_REQUEST)
            {
                l_DcmReturn_e = DCM_E_REQUEST_NOT_ACCEPTED;
            }
            break;

        case 0x27:
        case 0x31:
            if(ReqType == DCM_FUNCTIONAL_REQUEST)
            {
                l_DcmReturn_e = DCM_E_REQUEST_NOT_ACCEPTED;
            }
            else if(((*RequestData)&0x80) != 0x00)
            {
                *ErrorCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;
                l_DcmReturn_e = DCM_E_NOT_OK;
            }
            break;

        case 0x22:
        case 0x35:
        case 0x3E:
        default:
            break;
    }


    return l_DcmReturn_e;
}
/***********************************************************************************************************************
 *  ServiceRequestNotification_Confirmation()
***********************************************************************************************************************/
/*! \brief         Finishes supplier specific actions on a diagnostic service request.
 *  \details       This function is a notification from the DCM to the application that a diagnostic service processing
 *                 is finished.
 *  \param[in]     SID                 Contains the diagnostic service Id
 *  \param[in]     ReqType             Specifies the diagnostic request type:
 *                                     0 - physical request
 *                                     1 - functional request
 *  \param[in]     SourceAddress       Contains the diagnostic client source address
 *  \param[in]     ConfirmationStatus  Contains the response transmission resp. diagnostic response type
 *  \return        E_OK                The operation is finished
 *  \return        E_NOT_OK            The operation has failed. Has no effect on DCM.
 *  \context       TASK
 *  \reentrant     FALSE
 *  \synchronous   TRUE
 *  \pre           -
***********************************************************************************************************************/
FUNC(Std_ReturnType, DCM_CALLOUT_CODE) ServiceRequestNotification_Confirmation(uint8 SID, uint8 ReqType, uint16 SourceAddress, Dcm_ConfirmationStatusType ConfirmationStatus)
{

}

案例测试

1.案例1

2E服务不支持功能寻址,ECU接收到2E服务请求,则不响应

物理寻址2E服务,回复肯定响应

功能寻址2E服务,不响应

2.案例2

19服务不支持抑制肯定响应,ECU接收到19 8x xx请求,则响应NRC12

19 01 FF请求,回复肯定响应

19 81 FF请求,回复NRC12

3.案例3

11服务需要NRC22条件(车速小于3km/h)检测,当车速大于3km/h时ECU接收到11 01请求,则响应NRC22

在车速为0km/h时,11 01请求,回复肯定响应

在车速为5km/h时,11 01请求,回复NRC22

  • 17
    点赞
  • 115
    收藏
    觉得还不错? 一键收藏
  • 24
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值