诊断会话层DSL

简介: 诊断会话层DSL.

前言

  • 诊断会话层:Diagnostic Session Layer - DSL
  • DSL 子模块的所有功能区域应符合规范 ISO14229-1、ISO14229-2 和 ISO15765-3 的网络独立部分
  • DSL 子模块中不存在依赖于网络的功能区域,不过,在配置中,一些参数的设置会依赖网络部分

用例

  • DSL 子模块提供以下功能
  • 会话处理(根据 ISO14229-1 和 ISO15765-3 的要求)
  • 应用层定时处理(根据 ISO14229-1 和 ISO15765-3 的要求)
  • 特定响应行为(根据 ISO14229-1 和 ISO15765-3 的要求)
  • 每个诊断连接的身份验证状态处理(根据 ISO14229-1:2018 的要求)
  • 为每个连接提供身份验证状态
  • 管理身份验证状态转换

关联模块

  • DSL与其他模块有以下交互:
模块 关系
PduR 模块 PduR 模块提供传入诊断请求的数据 | DSL 子模块触发诊断响应的输出
DSD 子模块 DSL 子模块向 DSD 子模块通知传入请求并提供数 | DSD 子模块触发诊断响应的输出
DSP 子模块 DSL 子模块提供对安全和会话状态的访问
SW-C 模块 DSL 子模块提供对安全和会话状态的访问
ComM 模块 DSL子模块保证 ComM 模块所需的通信行为

功能概述

  • DSL子模块提供了以下功能:
功能 描述
请求处理 将请求从 PduR 模块转发到 DSD 子模块 | 实现 “TesterPresent” 功能,保持当前会话(keep alive logic)
响应处理 将 DSD 子模块的响应转发到 PduR 模块 | 对诊断设备的响应时间的保障,进行超时处理 | 支持周期传输 | 支持 ROE(ResponseOnEvent)传输 | 支持分段响应 | 支持由应用程序触发的 ResponsePending 响应
安全级别处理 管理安全级别
会话状态处理 管理会话状态 | 跟踪非默认会话的活动时间 | 允许修改会话的计时
诊断协议处理 不同诊断协议的处理 | 管理资源
通信方式处理 处理通讯请求(Full- / Silent- / No Communication) | 指示诊断的当前状态是激活还是非激活 | 启用/禁用所有类型的诊断传输

将请求从 PduR 模块转发到 DSD 子模块

  • 每当在分配给 Dcm 模块的 DcmDslProtocolRxPduId 上开始接收新的诊断请求内容时
  • PduR 调用 Dcm_StartOfReception 通知 Dcm 模块接收的数据大小,并提供第一帧或单帧的数据,如果数据规模溢出缓冲区大小或者如果请求的服务不可用,允许 Dcm 拒绝接收诊断数据
  • PduR 模块之后调用 Dcm_CopyRxData 函数请求 Dcm 模块将数据拷贝到 Dcm buffer
  • 如果 Dcm 模块诊断请求接收完成(当 Dcm_StartOfReception 函数返回成功),PduR 模块就会调用 Dcm_TpRxIndication 给 Dcm 模块一个接收指示
  • Dcm 应能够使用通用连接,其中寻址信息由 Dcm_StartOfReception 通过 DcmRxPdu 的元数据提供给 Dcm。必须存储此寻址信息并将其用于响应和检测来自同一测试仪的请求
  • 当 Dcm_TpRxIndication 返回 Result = E_OK 后 DSL 子模块才会将接收到的数据转发给 DSD 子模块
  • 一旦收到请求消息(调用 Dcm_TpRxIndication 返回 Result = E_OK 后),DSL子模块应阻止相应的 DcmPduId 直到调用 Dcm_TpTxConfirmation
  • 在处理请求期间,没有相同 DcmDslConnection 的其他请求(例如,增强会话可以通过 OBD 会话结束)可以被接收,直到发送相应的响应消息并且再次释放 DcmPduId(并发 TesterPresent 请求除外)。允许具有用于不同诊断通信应用的不同 DcmPduId。例如:
  • OBD DcmDslProtocolRxPduId: 用于接收 OBD 请求
  • OBD DcmTxPduId: 用于 OBD 响应发送
  • UDS phys DcmDslProtocolRxPduId: 用于接收 UDS 物理寻址请求
  • UDS func DcmDslProtocolRxPduId: 用于接收 UDS 功能寻址请求
  • UDS DcmTxPduId: 用于 UDS 响应发送
  • 地址类型(物理/功能寻址)是根据 DcmDslProtocolRxPduId 配置的。每个DcmDslProtocolRxDuId 的配置是可变的,因为功能寻址和物理寻址接收总是有不同的 DcmDslProtocolRXDuId 值,而与传输层的寻址格式无关(扩展寻址、正常寻址)

保持当前会话

  • Tester 诊断仪可能会并行发送功能寻址 “TesterPresent” 请求和物理寻址请求/响应。这在 ISO14229-1 中被称为 “keep alive logic”
  • 功能寻址 “TesterPresent” 请求是不需要响应的
  • 当 PduR 模块调用 Dcm_TpRxIndication 函数返回 Result=E_OK 时,并且如果当请求是 “TesterPresent” 且 “suppressPosRspMsgIndicationBit” 设置为 TRUE 时(0x3e 0x80),DSL 子模块应重置会话超时定时器(S3Server)
  • 当 PduR 模块调用 Dcm_TpRxIndication 函数返回 Result=E_OK 时,并且如果当请求是 “TesterPresent” 且 “suppressPosRspMsgIndicationBit” 设置为 TRUE 时(0x3e 0x80),DSL 子模块不应将此请求转发给 DSD 子模块进行进一步处理
  • 由于绕过了 DSL 子模块中的 “TesterPresent” 功能,Dcm 模块能够毫不延迟地接收和处理下一个物理请求
  • “TesterPresent” 请求只能是功能寻址且 “suppressPosRspMsgIndicationBit” 设置为 TRUE 时被 Dcm 模块处理

将 DSD 子模块的响应转发到 PduR 模块

  • DSD 子模块应请求 DSL 子模块传输响应
  • 当 DcmDslMainConnection 诊断响应就绪时,DSL 子模块通过调用 PduR_DcmTransmit 函数触发诊断响发送
  • 在周期性发送的情况下,Dcm 应在调用 PduR_DcmTransmit() 时提供完整的有效负载数据,并且不期望调用 Dcm_CopyTxData 函数
  • 在周期性发送的情况下,将调用 Dcm 进行周期性传输,并使用Dcm_TxConfirmation 来指示传输结果
  • DcmTxPduId 伴随着响应被一起发送出去,DcmTxPduId 在 Dcm 模块配置中链接到 DcmDslProtocolRxPduId,即收到请求的 ID(参见配置参数DcmDslProtocolTx),在 PduR_DcmTransmit() 中,只有长度信息和一般连接的寻址信息被提供给 PduR 模块
  • 在 Dcm 模块成功调用 PduR_DcmTransmit() 之后,PduR 模块将调用 Dcm_CopyTxData 请求 Dcm 模块提供要传输的数据,当完整的 PDU 发送成功或发生错误时,PduR 模块将调用 Dcm_TpTxConfirmation
  • 如果 DSL 子模块在成功发送完整的 Dcm PDU 后收到确认,或者调用 Dcm_TpTxConfirmation 发生错误,那么 DSL 子模块应将此确认转发给 DSD 子模块
  • 如果传输失败(PduR_DcmTransmit() 请求失败)或确认错误(Dcm_TpTxConfirmation 返回错误),DSD 子模块将不再重复诊断响应发送
  • 注意:只有当 PduR_DcmTransmit 成功时才需要 Dcm_TpTxConfirmation
  • 如果 DcmDslProtocolTx 的 Multiplicity 设置为 0,则 Dcm 只处理接收到的诊断请求而不发送响应

通用连接处理

  • Dcm 应能够处理由 DcmPdus 识别的具有 SOURCE_ADDRESS_16 和 TARGET_ADDRESS_16 类型的 MetaDataItems 的通用连接
  • 这些连接在运行时携带实际的测试地址
  • 通用连接支持通过 IP 和 FlexRay 进行诊断,以及根据 ISO15765-2 使用正常固定或混合 29 位寻址格式进行 CAN 诊断
  • 根据 CAN ID 的实际布局,通用连接也可以用于扩展或普通和混合 11 位寻址格式
  • Dcm 不知道 CanTp 使用的实际寻址格式
  • 多个连接可能引用相同的 DcmPdus
  • 通用连接应一致,这意味着一个 DcmDslConnection (DcmDslProtocolRxPduRef, DcmDslProtocolTxPduRef, DcmDslPeriodicTxPduRef)的所有引用 PDU 的 MetaDataItems 和 PduLength 是相同的
  • 必须存储通过通用连接接收的诊断请求的源地址,它在 MetaDataItem OURCE_ADDRESS_16 中通过 Dcm_StartOfReception 提供
  • 如果 Dcm 即将发送响应、事件响应或对一般连接请求的周期性消息,则 Dcm 应将 TARGET_ADDRESS_16 设置为 PduR_DcmTransmit() 中 MetaDataPtr 中存储的源地址的值
  • 通过通用连接接收的诊断请求的源地址应在应用程序的参数 TesterSourceAddress 中提供
  • 通过通用连接的诊断请求的目标地址可以在通过 Dcm_StartOfReception() 接收的 MetaDataItem TARGET_ADDRESS_16 中提供,此时,如果目标地址不等于配置的 ECU 地址 DcmDspProtocolEcuAddr, Dcm 将忽略物理请求
  • 通过通用连接传输的响应的源地址可以从配置参数 DcmDspProtocolEcuAddr 中读取
  • 注:如果同一 DcmDslProtocolRow 的某些传输诊断消息需要不同的源地址,则可以从 pdu 中省略 MetaDataItem SOURCE_ADDRESS_16,以便在下层配置该地址。对于物理请求也是如此,其中可以从 pdu 中省略 TARGET_ADDRESS_16

NRC 0x78

  • 如果应用程序(或 DSP 子模块)能够执行请求的诊断任务,但需要额外的时间来完成任务和准备回应,那么 DSL 子模块将发送一个 NRC 为 0x78 的否定响应(响应等待)
  • DSL 子模块保证了对 Tester 的响应时间
  • 对于一个诊断请求,NRC 0x78 的否定响应数量可以通过配置参数(DcmDslDiagRespMaxNumRespPend)加以限制以避免在应用程序死锁的情况下无休止的发送 NRC 0x78,如果不配置此参数,则 NRC 0x78 的默认负响应数为无限大

支持周期性发送

  • UDS 服务 ReadDataByPeriodicIdentifier(0x2A-根据周期标识符读取数据服务)允许测试仪向 ECU 请求周期性传输数据记录值,请求报文中可以包含了一个或者多个周期标识符(periodicDataIdentifier)
  • Dcm 模块应使用单独的协议和可配置大小的单独缓冲区发送周期性传输的响应
  • 根据通信方式的不同,Dcm 模块周期传输通信只能在完全通信模式下进行
  • 在未处于完全通信模式时可能发生周期性传输事件。因此存在以下要求:
  • Dcm 模块应丢弃全通信模式旁边的周期性传输事件,不将其排队传输
  • 周期性传输事件不应激活完整通信模式

支持分段响应(page -buffer)

  • 如果 DcmPagedBufferEnabled=TRUE,Dcm 模块应提供一种机制来发送大于配置和分配的诊断缓冲区的响应
  • 只有在 DcmPagedBufferEnabled 设置为 TRUE 时才会有 DcmDslProtocolMaximumResponseSize
  • 如果 DcmPagedBufferEnabled == TRUE,且生成的响应大 DcmDslProtocolMaximumResponseSize,则 Dcm 响应 NRC 0x14(DCM_E_RESPONSETOOLONG)
  • 如果 DcmPagedBufferEnabled == FALSE,并且为请求生成的响应大 Dcm_MsgContextType 结构元素 resMaxDataLen,则 Dcm 响应 NRC 0x14(DCM_E_RESPONSETOOLONG)
  • 使用分页缓冲处理,ECU 不会被迫提供与最大响应长度一样大的缓冲区。请注意:
  • 分页缓冲区处理仅用于发送-不支持接收
  • 分页缓冲区处理不适用于应用程序(仅在 Dcm 内部使用)
  • Dcm 应提供 TP 请求的正确数据量,如果请求的数据量不可用,则返回 BUFREQ_E_BUSY
  • 注意:如果请求的数据量不可用,Dcm 应该立即填满分页缓冲区

支持由应用程序触发的响应等待

  • 在某些情况下,例如在例程执行的情况下,应用程序需要立即响应(NRC 0x78-响应等待),而不是在到达响应时间之前(P2ServerMax/P2*ServerMax)
  • 当 Dcm 模块调用操作并获得错误状态 DCM_E_FORCE_RCRRP 时, DSL 子模块将触发 NRC 0x78(响应等待)的负响应传输,此响应需要从单独的缓冲区发送,以避免覆盖正在进行的请求处理

管理安全级别

  • DSL 子模块将保存当前活动安全级别
  • 为了访问这个级别,DSL 子模块提供了以下接口:
  • 获取当前活动的安全级别:Dcm_GetSecurityLevel
  • 设置新的安全级别:DslInternal_SetSecurityLevel
  • 初始化 Dcm 时,安全级别设置为 0x00 (DCM_SEC_LEV_LOCKED)
  • 在以下情况下,DSL 应该将安全级别重置为 0x00
  • 会话状态发生改变
  • S3Server 定时器超时
  • 如果不配置 DcmDspSecurityNumAttDelay,则同一 DcmDspSecurityRow 上的 DcmDspSecurityAttemptCounterEnabled 设置为 FALSE
  • 只有当 DcmDspSecurityRow 的 DcmDspSecurityAttemptCounterEnabled 设置为 TRUE 时,才会出现 DcmDspSecurityResetAttemptCounterOnTimeout
  • 初始化时,对于每个 DcmDspSecurityRow 表项,DcmDspSecurityAttemptCounterEnabled 配置参数设置为 TRUE
  • 为了获得每个 DcmDspSecurityRow 条目的 AttemptCounter 的值,应该调用相应的 Xxx_GetSecurityAttemptCounter
  • 如果 Xxx_GetSecurityAttemptCounter 返回 E_NOT_OK,则将尝试将计数设置为对应 SecurityLevel 的 DcmDspSecurityNumAttDelay 中配置的值
  • 如果任何 Xxx_GetSecurityAttemptCounter 操作返回 DCM_E_PENDING,Dcm 应该中断 Xxx_GetSecurityAttemptCounter() 的调用,以便在下一个 Dcm_MainFunction() 循环中恢复这条调用链
  • 只有当 DcmDspSecurityUsePort 设置为 USE_ASYNCH_FNC 且 DcmDspSecurityAttemptCounterEnabled 设置为 TRUE 时,才会出现 DcmDspSecurityGetAttemptCounterFnc
  • 如果在 DcmDspSecurityMaxAttemptCounterReadoutTime 中配置的 Dcm_MainFunction() 第一次调用之后的延迟已经达到,并且所有的 Xxx_GetSecurityAttemptCounter 还没有被调用(即一个操作在之前的 Dcm_MainFunction() 循环中返回了一个 DCM_E_PENDING 状态),则挂起的操作应该通过调用 OpStatus 设置为 DCM_CANCEL 来取消
  • 未通过调用其 Xxx_GetSecurityAttemptCounter 获取过的 AttemptCounters 应使用相应安全级别的 DcmDspSecurityNumAttDelay 中配置的值初始化
  • 一旦成功或不成功地检索了所有的 AttemptCounter 值(所有 Xxx_GetSecurityAttemptCounter() 操作都已执行并返回了一个最终的、非 PENDING 的错误值,或者操作链已被取消),如果AttemptCounter 值中至少有一个大于或等于对应 DcmDspSecurityRow 配置的 DcmDspSecurityNumAttDelay,Dcm 根据 DcmDspSecurityRow 的 DcmDspSecurityDelayTimeOnBoot / DcmDspSecurityDelayTime 的值较高者启动 SecurityDelayTimer
  • 定时器(DcmDspSecurityDelayTime, DcmDspSecurityMaxAttemptCounterReadoutTime)如果配置为0,则认为定时器在启动时立即超时,即不具有延迟效应
  • DcmDspSecurityMaxAttemptCounterReadoutTime 应为 DcmTaskTime 的倍数,且至少等于DcmTaskTime
  • 成功的 sendKey 子函数请求将重置该安全级别的特定 AttemptCounter 的值
  • 如果 DcmDspSecurityResetAttemptCounterOnTimeout 设置为 TRUE,当 SecurityDelayTimer 定时时间达到时,Dcm 将重置该安全级别的特 AttemptCounter 的值
  • 当 Dcm 改变了 AttemptCounter 时,Dcm 应该调用 Xxx_SetSecurityAttemptCounter()(如果 DcmDspSecurityRow 对应的配置参 DcmDspSecurityAttemptCounterEnabled 被设置为 TRUE)来通知应用程序计数器的变化
  • 只有当 DcmDspSecurityUsePort 设置为 USE_ASYNCH_FNC 并且 DcmDspSecurityAttemptCounterEnabled 设置为 TRUE 时,才会出现 DcmDspSecuritySetAttemptCounterFnc

管理会话状态

  • DSL 子模块应该保存当前活动会话的状态
  • 为了访问这个变量(会话状态),DSL子模块提供了以下接口:
  • 获取当前活动会话: Dcm_GetSesCtrlType
  • 设置一个新会话: DslInternal_SetSesCtrlType()
  • 初始化 Dcm 时,会话状态设置为该值 0x01(默认会话)
  • 调用 Dcm_ResetToDefaultSession 允许应用程序将当前会话重置为默认会话,并通过调用 SchM_Switch_<bsnp>_DcmDiagnosticSessionControl(RTE_MODE_DcmDiagnosticSessionControl_DCM_DEFAULT_SESSION)调 ModeDeclarationGroupPrototype DcmDiagnosticSessionControl 的模式切换
  • 示例:超出速度限制时自动终止扩展诊断会话

管理认证状态

  • Dcm 提供了经过身份验证的诊断方法,DSL子模块为每个诊断连接提供身份验证状态
  • 它在启动时初始化此状态,注意:在连接空闲一段时间后要回退到非身份验证状态
  • Dcm 应根据配置的 DcmDslConnection 提供身份验证状态
  • Dcm 应通过 ModeDeclarationGroupPrototype DcmAuthentication_ 提供每个身份验证状态的状态
  • Dcm 维护身份验证状态,并将此状态镜像到模式声明组 DcmAuthentication_
  • 此模式声明组仅由 Dcm 更改,但是更改此状态的应用程序对 Dcm 身份验证状态没有影响
  • Dcm 应支持每个连接的两种身份验证状态:deauthenticated(去认证状态)、authenticated(已认证状态)
  • 启动时,Dcm 处于未经身份验证的状态或恢复持久状态,只有在客户端成功执行身份验证序列之后,才能转换到已认证状态
  • 在某些使用情况下,如在生产中,会执行频繁的通电/断电,为了在断电时保持已实现的身份认证状态,有一个专用模式规则请求 Dcm 保持已认证的状态
  • 如果没有配置 DcmDspAuthenticationPersistStateModeRuleRef,或者 DcmDspAuthenticationPersistStateModeRuleRef 引用的模式规则被评估为 false,Dcm 将在 Dcm_Init 中初始化所有身份验证状态为去认证状态
  • 如果 DcmDspAuthenticationPersistStateModeRuleRef 引用的模式规则被评估为 true, Dcm 将初始化每个连接上的持久身份验证状态,包包括每个连接上的角色和白名单
  • 验证状态之间的转换由 DSL 和 DSP 子模块控制,DSL 子模块负责将已认证状态回退到未认证状态,DSP 子模块负责从客户端触发的转换更改

  • 如果满足以下条件,Dcm 应将已配置的连接从已认证状态转换为未认证状态:
  • 在该连接上发送最后一个诊断响应时,Dcm 处于默认会话中
  • 配置了 DcmDspAuthenticationDefaultSessionTimeOut,且该连接在距上一次的 Dcm_TpTxConfirmation 的 DcmDspAuthenticationDefaultSessionTimeOut(单位:秒) 时间内没有收到有效的诊断请求
  • 如果 Dcm 处于非默认会话,S3server 超时时,Dcm 将对分配给该连接的非默认会话的身份认证状态执行从已认证状态转变为未认证状态
  • 如果连接的身份认证状态转变为未认证状态,Dcm 应清除该连接上所有持久的身份认证信息
  • 在从认证状态转换到未认证状态时,Dcm 将丢弃当前角色白名单,并使用从DcmDspAuthenticationDeauthenticatedRoleRef 中配置的去认证角色
  • 在某些用例中,希望应用程序设置角色,而不是使用诊断服务进行可能很耗时的证书解析
  • Dcm 提供 API Dcm_SetDeauthenticatedRole 覆盖已配置的去认证角色
  • 被覆盖的角色仅在未身份认证状态下有效,不会被持久化,并由证书通过服务 0x29 提供的角色覆盖
  • 如果连接处于 deauthenticated(未认证) 状态并且调用 API Dcm_SetDeauthenticatedRole,Dcm 将使用 deauthenticatedRole 作为该连接上的每一个新的角色的认证状态
  • 只有当连接处于去认证状态时,Dcm 才会处理 Dcm_SetDeauthenticatedRole 的调用
  • Dcm_SetDeauthenticatedRole 设置的去认证角色在连接执行过渡认证状态时被丢弃
  • 在启动时,ECU 应始终使用在 DcmDspAuthenticationDeauthenticatedRoleRef 中配置的去认证状态

跟踪活动的非默认会话

  • 当一个非默认会话处于活动状态时,当会话超时(S3Server)到达而没有收到任何诊断请求时,DSL 子模块将重置到默认会话状态(“DefaultSession”,0x01)
  • 调用 SchM_Switch_<bsnp>_DcmDiagnosticSessionControl(RTE_MODE_DcmDiagnosticSessionControl_DEFAULT_SESSION) 来调用 ModeDeclarationGroupPrototype DcmDiagnosticSessionControl 的模式切换。注意: <bsnp>是 BSW 调度器名称前缀
  • S3Server 超时定时器的启动条件如下(“S3Server的启动”意味着重置计时器并从开始开始计数):
  • 完成任何最终响应消息或错误指示(Dcm_TpTxConfirmation:确认完整 PDU 或提示错误)
  • 在不需要/不允许任何响应消息(响应和负响应)的情况下完成所请求的操作
  • 指示在接收多帧请求消息时出现错误(Dcm_TpRxIndication: 错误指示)
  • S3Server 超时定时器的关闭条件如下:
  • 多帧请求报文的开始(Dcm_StartOfReception: 表示 PDU 接收的开始)
  • 接收单帧请求消息(Dcm_StartOfReception: PDU 接收开始)

允许修时序参数

  • Dcm 模块应处理以下符合 ISO14229-2 的协议时序参数: P2ServerMin, P2ServerMax, P2*ServerMin, P2*ServerMax, S3Server
  • P2min / P2*min 和 S3Server 设置为定义值: P2min = 0ms, P2*min = 0ms, S3Server = 5s.
  • 这些协议定时参数对会话层定时有影响(对传输层定时没有影响)
  • 当协议处于激活状态时,可以通过以下方式修改其中一些定时参数:
  • 10 服务 - DiagnosticSessionControl
  • 83 服务 - AccessTimingParameter
  • DSL 子模块提供以下功能来修改时序参数:
  • 提供活动时序参数
  • 设置新的时序参数。只有在发送响应之后才允许生效

不同的服务表

  • 不同的协议允许设置不同的诊断服务(例如,用于增强诊断的 UDS 命令,用于 OBD 协议的 OBD 模式服务)
  • 可以创建不同的服务表并将它们链接到诊断协议
  • 每次协议初始化时,DSL 子模块都会设置到相应服务表的链接(见配置参数 DcmDslProtocolSIDTable)
  • DSD 子模块使用此链接进一步处理诊断请求

协议的优先级

  • 配置参数 DcmDslProtocolPriority 可以为每个协议赋予自己的相对优先级
  • 可能的用例:ECUs、与车辆内部诊断测试仪通信(运行增强型诊断)、车辆外部 OBD-II/WWH-OBD 测试仪进行通信
  • OBD-II/WWH-OBD 通信的优先级必须高于增强诊断
  • 由于协议配置中引用了不同的 DcmDslProtocolRxDuId 值(见配置参数 DcmDslProtocolRxDuRef),因此可以区分诊断协议

协议的优先权

  • 如果正在运行的诊断请求被更高优先级的请求抢占,DSL 子模块应调用抢占协议上配置的所有 Xxx_StopProtocol() 函数
  • XXX_StopProtocol 函数通过配置参数 DcmDslCallbackDCMRequestService 进行配置
  • 协议抢占不能被高优先级协议的 Concurrent testpresent(3E 80) 激活
  • 如果协议被抢占,并且该协议有一个正在运行的等待响应传输,Dcm 需要调用 PduR_DcmCancelTransmit(),参数如下: PduId:要取消的 Pdu 的 id
  • 当 PduR_DcmCancelTransmit() 返回 E_NOT_OK 时,Dcm 模块应停止当前协议
  • 如果正在运行的诊断请求被更高优先级的请求抢占,当 Dcm_OpStatus 设置为 DCM_CANCEL 时,Dcm 将取消所有在抢占协议上的外部挂起操作
  • 如果对 Dem 的操作正在挂起,并且新请求也需要与 Dem 进行交互,Dcm 接受新的请求,并使用新请求中的参数调用相应的 Dem API
  • 如果 Dcm 正在抢占一个挂起的接收协议,Dcm 模块将使用 PduR_DcmCancelReceive() 调用取消接收
  • 如果 PduR_DcmCancelReceive() 返回 E_NOT_OK, Dcm 将停止当前协议
  • 如果高优先级协议处于默认会话中,并且没有活动请求处于执行阶段,则低优先级或相同优先级的请求可以抢占高优先级协议,在这种情况下,DSL 子模块将调用所有配置的 Xxx_StopProtocol() 函数(见配置参数 DcmDslCallbackDCMRequestService)
  • 应能够处理具有同等优先级的协议
  • 如果诊断请求由于优先级较高的协议而无法处理,并且 DcmDslDiagRespOnSecondDeclinedRequest 设置为 True,Dcm 应为未处理的请求发送 NRC 0x21(BusyRepeatRequest)
  • 如果由于优先级较高的协议而无法处理诊断,并且 DcmDslDiagRespOnSecondDeclinedRequest 设置为 False,则 Dcm 将忽略该请求。在这种情况下,根本不会生成响应消息
  • 在多个客户端具有不同的 PduID 请求相同协议的情况下,由于同一协议的所有连接都具有相同的优先级,第二个请求(具有不同的 RxPduId)将不被处理,如果配置参数 DcmDslDiagRespOnSecondDeclinedRequest 为 TRUE,对于第二个请求,将发出 NRC 0x21 (BusyRepeatRequest) 的否定响应,如果配置参数为 FALSE,则不响应
  • 注意:
  • 每个 DcmDslProtocol 可以配置多个 RxPduID
  • 这些 RxPduID 可以通过 PduR 配置连接到不同的测试仪
  • 这意味着许多测试仪(Tester)可能被配置为相同的协议
  • 这代表一个非 UDS 扩展/用例,为了有一个符合 UDS 的流,每个测试仪(Tester)应该有一个 DcmDslProtocol 实例
  • 在诊断并行请求的情况下,与活动请求相同或更低优先级的请求将不会调用 ComM API(ComM_DCM_ActiveDiagnostic, ComM_DCM_InactiveDiagnostic)

并行诊断协议处理

  • 在今天的车辆中,同时连接多个测试仪是一个常见的场景,为了最大限度地减少多个测试仪并发请求之间的干扰,Dcm 支持并行诊断服务处理,此行为符合 ISO 14229-1 Appendix J。
  • 有一些限制,在非默认会话中,只允许来自一个诊断仪的诊断通信
  • 在默认会话和 OBD-II 通信中,可以并行处理诊断请求
  • 如果车辆配备了所谓的 “OBD 加密狗” 或电子记录设备,则并行 OBD 和 UDS 通信尤为重要,这些设备由车主安装,通过标准化的 OBD 服务进行诊断通信,此类设备的存在应尽可能减少对车辆内部 UDS 通信的干扰
  • 因此,只要有可能,Dcm 就支持并行处理
  • 在默认会话中处理并行请求,如果 Dcm 接收到一个请求,并且当前在非默认会话中没有更高优先级的协议,Dcm 将接受新的传入请求并处理它
  • 在非默认会话中没有并行处理,如果 Dcm 接收到一个请求,并且具有更高优先级的另一个协议当前处于非默认会话中,Dcm 应拒绝新接收到的请求
  • 一些 Dcm 接口提供对不同诊断服务的访问,例如,接口 RoutineService 用于 RoutineControl (0x31) 的子函数 Start, Stop 和 Request Result,或者接口 DataServices 用于 Read 和 Write 操作,在这些接口上,在任何时间点只有一个客户端可以访问数据
  • 延迟同一接口上的并行处理,如果 Dcm 接收到一个请求,并且该请求的服务处理需要调用当前正在处理另一个请求的同一接口,则 Dcm 将延迟对该接口的调用,直到该接口上运行的操作完成
  • 如果 Dcm 需要延迟处理,其应当符合 P2 和 NRC 0x78 的标准定时行为,从外部的角度来看,对应用程序的延迟调用看起来像是应用程序本身花费了更多的时间来执行
  • Dcm 需要并行处理 UDS 请求和 OBD-II 请求,在这种情况下,根据 [SWS_Dcm_00015] 跳过协议优先级检查,不进行协议抢占??
  • 使用容器 DcmDslProtocolRow, Dcm 配置支持多种协议,每个协议都有一个配置好的 DcmDemClientRef 来定义与 Dem 交互的 Dem 客户端,该客户端 ID 允许 Dem 区分同一函数或一组函数的 Dcm 的并发调用,以处理某个请求
  • 在处理从给定协议接收到的诊断请求时,Dcm 应确定被处理协议的 DcmDslProtocolRow 的 DcmDemClientRef,Dcm 将在所有以 ClientId 作为参数的 Dem API 调用中使用此值
  • 对同一接口的多个调用的序列化,在并行诊断服务处理期间,Dcm 应在内部序列化所有异步 C/S 接口或 C 函数调用到相同的端口接口或 C 函数
  • 如果 Dcm 接收到的请求的优先级高于当前处理的请求,并且当前正在处理非默认会话中的诊断服务,Dcm 应取消正在运行的诊断请求,过渡到默认会话并处理新接收到的请求
  • 集成商将为 OBD 协议分配最高优先级,以满足法律规定的响应和时间要求,因此,所有 “高优先级协议” 的定义都适用于使用 OBD 的用例
  • 如果 Dcm 在默认会话中处理来自高优先级协议的请求,并且 Dcm 正在接收一个诊断请求,要求在非默认会话中进行更改,Dcm 应该延迟会话更改请求,直到高优先级协议服务完成,然后转换到所请求的非默认会话
  • 对单一 OBD 协议的限制,Dcm 只能支持一个 DcmDslProtocolRow,配置的 DcmDslProtocolType 设置为 DCM_OBD_ON_<XYZ>
  • OBD 协议具有最高优先级,Dcm 应支持 DcmDslProtocolRow, DcmDslProtocolType 设置为 DCM_OBD_ON_<XYZ> 为最高优先级

协议启动检测

  • 对于诊断协议的第一次请求,DSL 子模块将调用所有配置的 Xxx_StartProtocol() 函数(见配置参数 DcmDslCallbackDCMRequestService),在这个函数中,应用程序可以检查环境条件并启用/禁用协议的进一步处理
  • 在所有 Xxx_StartProtocol() 函数返回 E_OK 之后(意味着所有组件都允许协议启动),默认定时参数是从默认会话配置中加载的(见配置参数 DcmDspSessionRow)
  • 协调接口和模式之间的命名,DcmDspSessionRow 的短名称应该与 Dcm_SesCtrlType 和 DcmDiagnosticSessionControl 的模式声明的名称匹配,“DCM_” 前缀对于所有短名称都是强制性的
  • 为 ISO 标准化诊断会话提供标准化名称,DcmDspSessionLevel 的以下值代表 ISO 定义的诊断会话,将用于 DcmDspSessionRow 的短名称:
  • DCM_DEFAULT_SESSION
  • DCM_PROGRAMMING_SESSION
  • DCM_EXTENDED_DIAGNOSTIC_SESSION
  • DCM_SAFETY_SYSTEM_DIAGNOSTIC_SESSION
  • 在所有 Xxx_StartProtocol() 函数返回 E_OK 之后(这意味着所有组件都允许启动协议),以下操作也会被完成
  • 设置服务表设置(见配置参数 DcmDslProtocolSIDTable)
  • 重置安全状态
  • 会话状态重置为默认会话
  • 如果 Xxx_StartProtocol() 不返回 E_OK, Dcm 将返回 NRC 0x22

协议停止

  • 只有在协议被抢占的情况下,才会出现协议停止
  • 当 Dcm_TpTxConfirmation 的接收连接到 DSL 子模块给出的响应时,Dcm 不停止当前协议(不调用xxx_StopProtocol)
  • 注意:一个协议(例如 OBD)将一直处于激活状态,直到重置或其他协议抢占
  • 如果 Xxx_StopProtocol() 不返回 E_OK, Dcm 将返回 NRC 0x22

管理资源

  • 由于资源有限,以下几点可以作为设计的提示:
  • 在 Dcm 模块中只允许使用和分配一个诊断缓冲区,然后使用该缓冲区处理诊断请求和响应
  • NRC 0x78(响应挂起)响应的输出是用一个单独的缓冲区完成的
  • paged-buffer 处理,如果启用 (DcmPagedBufferEnabled=TRUE), Dcm 模块应提供一种机制来发送大于配置和分配的诊断缓冲区的响应

通信方式处理

  • 通信模式处理是 Dcm 和 ComM 之间的接口,ComM 将信道的当前通信状态通知 Dcm,Dcm 调用 ComM 活跃诊断,防止 Ecu 关闭或休眠
  • ActiveDiagnostic 这个状态显示诊断请求是否使 ECU 保持清醒状态(ActiveDiagnostic ==’DCM_COMM_ACTIVE’),或者诊断请求是否不能防止 ECU 关闭/休眠 (ActiveDiagnostic ==’DCM_COMM_NOT_ACTIVE’)。应用程序可以根据系统条件更改ActiveDiagnostic 状态
  • 应用程序将通过调用 Xxx_SetActiveDiagnostic() 来通知 Dcm ActiveDiagnostic 状态
  • Dcm_Init 后,Dcm 将 ActiveDiagnostic 设置为 DCM_COMM_ACTIVE
  • 如果调用 Xxx_SetActiveDiagnostic() 传参 false, 那么 ActiveDiagnostic 状态会被设置为 DCM_COMM_NOT_ACTIVE;如果传参 true,那么 ActiveDiagnostic 状态会被设置为 DCM_COMM_ACTIVE
  • Dcm 应等待来自的全通信模式指示
  • Dcm 在开始传输诊断应答之前,应等待来自 ComM 的全通信模式指示,等待时间不应超过从接收请求开始计算的 P2ServerMax
  • 如果 Dcm 无法确认等待传输的响应(DCM_E_FORCE_RCRRP),Dcm 将触发 Det 错误 DCM_E_FORCE_RCRRP_IN_SILENT_COMM
  • 注意:在接收端,在分段传输的情况下,静默通信模式可能导致请求丢失

No Communication - 无通信模式

  • ComM 模块将通过调用 Dcm_ComM_NoComModeEntered 向 Dcm 模块指示无通信模式
  • Dcm_ComM_NoComModeEntered 将禁用通信的所有类型的传输(接收和发送),这意味着消息接收和消息发送都将关闭
  • Dcm_ComM_NoComModeEntered 将禁用 ResponseOnEvent 传输
  • Dcm_ComM_NoComModeEntered 将禁用周期 id 传输(ReadDataByPeriodicIdentifier)
  • 当 Dcm_ComM_NoComModeEntered 被调用后,Dcm 模块将不再调用 PduR_DcmTransmit()函数

Silent Communication - 静默通信模式

  • ComM 模块将通过调用 Dcm_ComM_SilentComModeEntered 向 Dcm 模块指示静默通信模式,作为回应,Dcm 会立即关闭所有发送
  • Dcm_ComM_SilentComModeEntered 将禁用所有发送,这意味着消息发送将被关闭
  • Dcm_ComM_SilentComModeEntered 将禁用 ResponseOnEvent 传输
  • Dcm_ComM_SilentComModeEntered 禁用周期 id 传输(ReadDataByPeriodicIdentifier)

Full Communication - 完全通信模式

  • ComM 模块将通过调用 Dcm_ComM_FullComModeEntered 向 Dcm 模块指示完全通信模式
  • Dcm_ComM_FullComModeEntered 将开启所有类型的通信,这意味着消息接收和消息发送都是开启的
  • Dcm_ComM_FullComModeEntered 将启用 ResponseOnEvent 传输
  • Dcm_ComM_FullComModeEntered 将使能周期性传输(ReadDataByPeriodicIdentifier)
  • 调用 Dcm_ComM_FullComModeEntered 后,Dcm 将不受限制地处理DslInternal_ResponseOnOneDataByPeriodicId() 或 DslInternal_ResponseOnOneEvent() 函数

诊断激活状态

  • Dcm 将所有网络的内部诊断状态通知给 ComM 模块,网络上的诊断状态有两种选择
  • 在 “active” 诊断状态下,Dcm 处理来自该网络的一个或多个诊断请求,或者 Dcm 处于非默认会话中
  • 在 “inactive” 诊断状态下,Dcm 处于默认会话中,不在该网络上处理诊断请求
  • 当网络没有正在进行的通信时,Dcm 将诊断激活状态设置为 “inactive”
  • 当网络上有诊断通信时,Dcm 将诊断状态设置为 “active”
  • 在任何非默认会话中,诊断状态保持在 “active” 状态
  • 通信状态也可以通过 API Xxx_SetActiveDiagnostic 来控制
  • 如果在网络上收到诊断请求或诊断会话更改为任何非默认会话,Dcm 将进入 “active” 诊断状态
  • 当当前诊断请求处理完成并且 Dcm 没有处理该网络上另一个协议的诊断请求时,如果 Dcm 处于默认会话,则 Dcm 将在网络上进入 “inactive” 诊断状态
  • 如果发生 S3Server 超时,Dcm 将在所有网络上进入 “inactive” 诊断状态,并且 Dcm 将过渡到默认会话
  • 如果 ActiveDiagnostic 值为 DCM_COMM_ACTIVE,并且 Dcm 正在转换到诊断协议的 “active” 诊断状态,Dcm 将调用 ComM_DCM_ActiveDiagnostic(NetworkId),对于每个请求,通知 ComM 模块需要保持在完全通信模式
  • 当诊断状态转换为 “inactive” 时,Dcm 将通过调用 ComM_DCM_InactiveDiagnostic(NetworkId) 将网络上的非活动诊断状态通知 ComM 模块
  • 已完成的诊断请求的定义如下:
  • 通过接收连接到 DSL 子模块给出的响应的 Dcm_TpTxConfirmation, Dcm 发送了一个不等于 NRC 0x78 的正响应或负响应
  • Dcm 已经处理了 SPRMIB=true 的服务,正向响应被抑制
  • 在功能性寻址的情况下,Dcm 已经处理了服务,负面响应被抑制
目录
相关文章
|
存储 数据采集 人工智能
以Trace为核心的根因分析概述
近期一直在学习和复现“根因分析”领域的相关文章,在这里跟大家一起分享下相关内容。这里不在赘述关于“可观测性”和“AIOps”的重要性和必要性,也不过多的陈述在“复杂系统”中进行快速根因诊断的必要性,直接进入到相关算法和系统设计部分。
1583 0
以Trace为核心的根因分析概述
|
7月前
|
安全
[UDS] --- TesterPresent 0x3E
[UDS] --- TesterPresent 0x3E
159 1
|
Arthas 监控 Java
慢调用链诊断利器-ARMS 代码热点
慢调用链诊断利器-ARMS 代码热点
|
监控 网络架构
CAN-TP传输协议详解
CAN-TP传输协议详解
CAN-TP传输协议详解
|
7月前
|
存储 测试技术 API
诊断服务处理DSP
诊断服务处理DSP
371 0
|
7月前
|
存储 安全 测试技术
诊断服务调度DSD
诊断服务调度DSD
290 0
|
JSON 运维 监控
追踪问题——用Python Logging模块更轻松地诊断错误
追踪问题——用Python Logging模块更轻松地诊断错误
|
SQL 监控 数据库
【笔记】用户指南—诊断与优化—SQL审计与分析—日志分析
PolarDB-X支持SQL审计与分析功能,依托日志服务产品,提供强大的日志分析能力。本文将介绍常见场景的SQL日志分析语句及示例。
118 0
【笔记】用户指南—诊断与优化—SQL审计与分析—日志分析
|
SQL 存储 监控
【笔记】用户指南—诊断与优化—SQL审计与分析—简介
PolarDB-X联合日志服务推出SQL审计与分析功能,将SQL审计日志投递到日志服务中,实现了日志的实时查询、可视化分析、告警、投递、加工等操作。本文介绍SQL审计日志相关的信息。
116 0
【笔记】用户指南—诊断与优化—SQL审计与分析—简介
|
7月前
|
存储 API
功能定义
功能定义.
234 1
功能定义