4、DCM模块详解:请求处理流程、P2/P2*定时器与PDUR交互
好,咱们今天来啃DCM这块硬骨头。很多刚接触诊断栈的朋友,一上来就被DCM、PDUR、P2这些缩写搞晕了。其实说白了,DCM就是诊断通信的管理员,它负责把诊断请求接下来,分发给对应的处理模块,再把结果打包发回去。
我个人习惯把DCM看作整个诊断栈的“大脑”。它不直接干活,但它知道谁该干活、干多久、干不完怎么办。今天我们就把它拆开来看。
4.1 DCM的请求处理流程
一个诊断请求从CAN总线上进来,到最终响应发出去,中间经过了好几个关卡。我画了一张图,帮你把整个流程串起来。
你看,报文从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 | 具体服务实现(读数据、写数据、例程等) |
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*的切换逻辑:
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提供发送数据 |
嗯,这里还要提一下传输协议(TP)。当诊断报文超过单帧长度时,需要用到多帧传输。DCM本身不处理多帧的拆包和组包,这事交给PDUR和CanTp模块去做。DCM只关心完整的请求和响应数据。
举个例子,一个刷写请求可能有几千字节。CanTp负责把数据拆成多个CAN帧发送,PDUR负责把这些帧路由给DCM,DCM只看到最后拼好的完整数据。这种分层设计,说白了就是让每个模块只关心自己的事,别越界。