4、DCM模块详解:请求处理流程、P2/P2*定时器与PDUR交互

好,咱们今天来啃DCM这块硬骨头。很多刚接触诊断栈的朋友,一上来就被DCM、PDUR、P2这些缩写搞晕了。其实说白了,DCM就是诊断通信的管理员,它负责把诊断请求接下来,分发给对应的处理模块,再把结果打包发回去。

我个人习惯把DCM看作整个诊断栈的“大脑”。它不直接干活,但它知道谁该干活、干多久、干不完怎么办。今天我们就把它拆开来看。

4.1 DCM的请求处理流程

一个诊断请求从CAN总线上进来,到最终响应发出去,中间经过了好几个关卡。我画了一张图,帮你把整个流程串起来。

DCM请求处理流程 CAN报文到达 PDUR路由 DCM_StartOfReception DCM_ProcessRequest SID分发 DSP处理 DSL处理 DSD处理 响应发送 DCM内部划分为DSL(会话层)、DSD(服务分发)、DSP(服务处理)三个子模块

你看,报文从CAN进来后,先经过PDUR做路由判断。PDUR决定这个报文是发给DCM的,还是发给其他模块的。这一步很关键,我见过不少项目因为PDUR配置错了,诊断报文死活进不了DCM。

进入DCM后,先触发DCM_StartOfReception,告诉DCM“有活干了”。然后才是DCM_ProcessRequest,开始真正处理请求。DCM内部又分成三个子模块:

子模块 全称 职责
DSL Diagnostic Session Layer 会话管理、安全状态、定时器维护
DSD Diagnostic Service Dispatcher SID解析、服务分发、格式检查
DSP Diagnostic Service Processing 具体服务实现(读数据、写数据、例程等)
小提示:DSD负责“拆快递”,DSP负责“处理快递内容”,DSL负责“盯着时间别超时”。三个模块各司其职,缺一不可。

4.2 P2/P2*定时器机制

说到定时器,这是诊断开发里最容易踩坑的地方。P2和P2*这两个参数,很多人搞混。我刚开始做诊断时也犯过糊涂,有一次因为P2设得太短,ECU老是超时,测试部门追着我问了好几天。

P2和P2*到底是什么?

  • P2(Server Response Time):ECU处理一个诊断请求并给出响应的最大时间。默认一般是50ms。
  • P2*(Enhanced Response Time):当ECU需要更长时间处理时,可以发送NRC 0x78(请求正确,正在处理),然后进入P2*时间窗口。默认一般是5000ms。

你想想看,如果ECU收到一个刷写请求,50ms内肯定搞不定。这时候就需要P2*来救场。ECU先回一个0x78,告诉Tester“别急,我在忙”,然后Tester就会把等待时间从P2切换到P2*。

关键点:P2和P2*是从响应结束到下一个请求开始的时间,不是从请求到响应的时间。这个很多人搞反。

我画个时序图,帮你理解P2和P2*的切换逻辑:

P2 / P2* 定时器切换时序 Tester 请求 响应 ECU 处理中 NRC 0x78 继续处理 响应 P2 超时 P2* 超时 定时器切换逻辑 1. Tester发送请求后,启动P2定时器 2. ECU回复NRC 0x78,Tester切换到P2*定时器 3. ECU在P2*时间内完成处理并发送最终响应
避坑指南:我曾经在一个项目中,P2*设成了500ms而不是5000ms。结果刷写时ECU老是超时,查了两天才发现是配置表写错了。P2*的单位是毫秒,别写成秒。

4.3 DCM与PDUR的交互

PDUR(PDU Router)是DCM和底层通信模块之间的桥梁。DCM不直接和CAN驱动打交道,所有数据都通过PDUR来传递。

DCM和PDUR的交互主要有两个方向:

  • 接收方向:PDUR收到CAN报文后,调用DCM的DCM_StartOfReception和DCM_CopyRxData接口,把数据喂给DCM。
  • 发送方向:DCM要发响应时,调用PDUR的PduR_Transmit接口,把数据交给PDUR,PDUR再往下传给CAN驱动。

这里有个重要的配置点:PDUR的路由表。你得告诉PDUR,哪些CAN ID的报文是诊断报文,应该路由给DCM。我见过有人把物理寻址和功能寻址的ID配反了,结果功能寻址的请求全被当成物理寻址处理了。

接口名称 方向 说明
DCM_StartOfReception PDUR → DCM 通知DCM开始接收一个诊断请求
DCM_CopyRxData PDUR → DCM 把接收到的数据拷贝给DCM
DCM_TpHandler PDUR → DCM 传输协议处理(用于多帧报文)
PduR_Transmit DCM → PDUR DCM请求发送诊断响应
PduR_TriggerTransmit PDUR → DCM PDUR请求DCM提供发送数据
经验之谈:配置PDUR路由表时,建议把物理寻址和功能寻址分开配置。物理寻址走点对点,功能寻址走广播。我习惯在路由表里加注释,标明每个路由条目的用途,方便后续维护。

嗯,这里还要提一下传输协议(TP)。当诊断报文超过单帧长度时,需要用到多帧传输。DCM本身不处理多帧的拆包和组包,这事交给PDUR和CanTp模块去做。DCM只关心完整的请求和响应数据。

举个例子,一个刷写请求可能有几千字节。CanTp负责把数据拆成多个CAN帧发送,PDUR负责把这些帧路由给DCM,DCM只看到最后拼好的完整数据。这种分层设计,说白了就是让每个模块只关心自己的事,别越界。

总结一下:DCM是诊断栈的核心,它通过PDUR与底层通信模块解耦。P2/P2*定时器是诊断通信的“交通规则”,配置不对,整个诊断系统都会出问题。理解DCM的请求处理流程,是做好诊断栈开发的第一步。