在前面 《[CP_AUTOSAR]_通信服务_DCM模块(三)_DSL子模块(一)》文中,介绍了 DSL 子模块的整体功能,本文接着介绍从 PduR 模块到 DSD 模块提交的诊断请求。
2、提交诊断请求(从 PduR 到 DSD 子模块)
当 DcmDslProtocolRxPduId 开始接收新的诊断请求内容时,PduR 模块g汇报给 Dcm 模块。函数 Dcm_StartOfReception 会通知 DCM 模块即将接收的数据大小,提供单帧或者首帧的数据内容。如果接收的数据大小溢出了缓存空间,或者请求的服务不被允许,那么 DCM 模块会拒收此消息。函数 Dcm_CopyRxData 会进一步将缓存中的数据拷贝到 DCM 模块。如果诊断请求接收完成(即函数 Dcm_StartOfReception 执行成功),PduR 模块将会调用函数 Dcm_TpRxIndication 给 DCM 模块一个显示。函数 Dcm_StartOfReception 需要通过 DcmRxPdu 中的元数据来提供地址信息给 DCM 模块,这个地址信息是必须存储和使用的,以用于响应和检测来自同一上位机的请求。
[SWS_Dcm_00111] 只有在调用函数 Dcm_TpRxIndication 之后并且其返回值为 E_OK时,DSL 子模块才应该提交接收到的数据给到 DSD 模块;
[SWS_Dcm_00241] 诊断请求消息被成功接收(即函数 Dcm_TpRxIndication 返回值为 E_OK),并且直到完成 Dcm_TpTxConfirmation 函数的调用,DSL 模块都应该阻塞相应的 DcmPduId。在处理诊断请求过程中,像其它相同 DcmDslConnection 是不可能接收的(比如,增强型会话可以被 OBD 会话停止),直到相应的诊断应答消息被发送,并且 DcmPduId 被重新释放(除了 $3E 保持连接服务)。
不同的诊断通信应用,拥有不同的 DcmPduIds,例如:
1、OBD DcmDslProtocolRxPduId:接收 OBD 请求;
2、OBD DcmTxPduId:发送 OBD 应答;
3、UDS 物理寻址 DcmDslProtocolRxPduId:接收 UDS 物理地址请求;
4、UDS 功能寻址 DcmDslProtocolRxPduId:接收 UDS 功能地址请求;
5、UDS DcmTxPduId:发送 UDS 应答;
地址类型(物理地址/功能寻址)在 DcmDslProtocolRxPduId 参数中配置,功能寻址和物理寻址的接收在参数 DcmDslProtocolRxPduId 的值始终是不同的,其独立于传输层的寻址格式,因此每一个 DcmDslProtocolRxPduId 都有其自己的配置。
2.1、Dcm_StartOfReception
[SWS_Dcm_00444] 如果诊断请求的数据长度超出了缓存可用的空间,函数 Dcm_StartOfReception 应该返回值为 BUFREQ_E_OVFL;
[SWS_Dcm_00788] 当正在处理一个诊断请求时,并且参数 DcmDslDiagRespOnSecondDeclinedRequest(该参数的含义描述:对于第二个上位机 Client B 诊断请求所采取的行为) 被设置为 TRUE(即表示当无法处理第二个上位机的请求时,需要回复 NRC21(BusyRepeatRequest)),接收到使用不同的 DcmDslConnection(这是一个容器的名称,包含了不同通信协议的通道配置参数) 的诊断请求时,Dcm_StartOfReception 函数返回值应该为 BUFREQ_OK。
[SWS_Dcm_00789] 在需求 [SWS_Dcm_00788] 中,DCM 模块需要回复 NRC21(BusyRepeatRequest) ;
[SWS_Dcm_00790] 当正在处理一个诊断请求消息时,如果参数 DcmDslDiagRespOnSecondDeclinedRequest 被设置为 FALSE,DCM 模块应该拒绝任何一个新来的诊断请求(包括使用不同的 DcmDslConnection),一直到当前的诊断请求被处理完成。
[SWS_Dcm_00557] 当正在处理一个诊断请求消息时,DCM 模块应该拒绝任何一个新来的诊断请求(包括使用相同的 DcmDslConnection),一直到当前的诊断请求被处理完成。Concurrent TesterPresent(即$3E 80)被接收,返回值为 BUFREQ_OK ,但不会被进一步处理,因为正在运行中的诊断请求已经重置了会话超时计时器(S3Server)。
[SWS_Dcm_01145] 如果当前不是默认会话,并且在一个不同的 DcmDslConnection 上接收到了$3E 80服务,这个请求会被接收,且返回值为 BUFREQ_OK ,但不会被进一步处理。比如,不会重置会话超时计时器(S3Server)。
[SWS_Dcm_01146] 在 [SWS_Dcm_01145] 案例中,接收到一个更高优先级的协议时,不会导致协议抢占。
[SWS_Dcm_00642] 在函数 Dcm_StartOfReception 中消息长度 TpSduLength = 0,应该返回值 BUFREQ_E_NOT_OK。
[SWS_Dcm_00655] 如果当前不处于默认会话,并且接收到一个与当前激活的协议有相同或者更低优先级的协议,DCM 需要参考 [SWS_Dcm_00788] 和 [SWS_Dcm_00789] 和 [SWS_Dcm_00790] 的定义来作出相应的反应。
[SWS_Dcm_00656] 如果当前处于默认会话,正在处理一个诊断会话,并且接收到一个与当前诊断请求有相同或者更低优先级的协议,DCM 需要参考 [SWS_Dcm_00788] 和 [SWS_Dcm_00789] 和 [SWS_Dcm_00790] 的定义来作出相应的反应。
2.2、Dcm_CopyRxData
[SWS_Dcm_00443] 如果函数 Dcm_StartOfReception 返回值为 BUFREQ_OK,函数 Dcm_CopyRxData 应该进一步将缓存中的数据拷贝到 DCM 缓存中,并且更新参数 bufferSizePtr ,表示在完成接收后还剩余的可用缓存空间。
[SWS_Dcm_00996] 当调用函数 Dcm_CopyRxData 时,SduLength = 0,即接收的消息长度为0,应该返回值为 BUFREQ_OK,并且设置 bufferSizePtr 参数为接收缓存空间剩余的大小。
[SWS_Dcm_00342] 当开始拷贝接收数据时,DCM 模块不应该访问接收缓存,直到函数 Dcm_TpRxIndication 通知 DCM 模块成功的接收或者是接收不成功的终止了。
2.3、Dcm_TpRxIndication
[SWS_Dcm_00344] 调用函数 Dcm_TpRxIndication ,并且其返回值结果不为 E_OK,那么 DCM 模块就不用评估分配给 I-PDU 的缓存,I-PDU 在参数 DcmRxPduId 中。