4、网络层故障分析:多帧传输超时、流控制帧丢失、连续帧序号错误、报文长度不匹配
网络层,说白了就是UDS通信的「运输大队长」。它负责把应用层的诊断数据,一包一包地送到对方手里。如果网络层出了问题,你发出去的请求就像石沉大海,或者对方回了一堆乱码。
我个人习惯,遇到通信故障,先查网络层。因为应用层再复杂,底层传不过去,一切都是白搭。今天咱们就聊聊网络层最常见的四类故障:多帧传输超时、流控制帧丢失、连续帧序号错误、报文长度不匹配。
4.1 多帧传输超时
什么是多帧?就是一条诊断数据太长,一个CAN报文装不下,得分好几段发。比如写一个2KB的Bootloader数据,就得拆成几十帧。
多帧传输有个「时间窗口」的概念。发送方发完一帧,得在规定时间内收到对方的流控制帧,才能继续发下一帧。如果超时了,发送方就会认为通信断了。
超时的典型场景:
- 接收方太忙,没来得及回流控制帧
- 总线负载过高,流控制帧被延迟了
- 接收方压根没收到上一帧(丢帧了)
关键参数:
N_As(发送超时):发送方等待流控制帧的最大时间,通常为1000ms。
N_Bs(接收超时):接收方等待连续帧的最大时间,通常为1000ms。
N_Cr(连续帧间隔):发送方发连续帧的最小间隔,通常为0~100ms。
我在项目中遇到过一台ECU,每次写大数据都会超时。抓日志一看,N_As设成了100ms,但ECU内部处理流控制帧需要200ms。说白了,就是时间参数没匹配上。改一下N_As到500ms,问题就解决了。
排查技巧:
用CAN工具抓一下总线报文,看流控制帧的到达时间。如果每次都卡在超时边界上,大概率是时间参数设置不合理。
4.2 流控制帧丢失
流控制帧(FC帧)是接收方发给发送方的「通行证」。它告诉发送方:你可以发了,或者你等一会儿再发,或者你发慢一点。
如果流控制帧丢了,发送方会一直等,直到超时。你想想看,发送方傻傻地等着,接收方也在傻傻地等着,两边都以为对方有问题。
流控制帧丢失的原因:
- 总线错误导致报文被破坏
- 接收方发送缓冲区溢出,FC帧被丢弃
- 接收方压根没生成FC帧(软件Bug)
我曾经排查过一个案例:ECU在特定条件下会丢FC帧。后来发现是接收方的CAN驱动在中断里处理时间太长,导致FC帧发送被延迟,最终被发送方的超时机制「误杀」了。嗯,这里要注意,中断服务程序里别干太多活。
避坑指南:
我曾经遇到一个ECU,它的FC帧发送逻辑有Bug——只有在收到完整的第一帧后才发送FC帧。但协议要求是:收到第一帧后,必须立即回复FC帧。这个Bug导致多帧传输永远无法完成。所以,实现FC帧发送时,一定要严格按照ISO 15765-2的时序要求。
4.3 连续帧序号错误
多帧传输中,连续帧(CF帧)是有序号的。序号从1开始,到15循环。接收方靠序号来拼接数据。如果序号错了,接收方就会认为数据乱了,直接丢弃整个多帧消息。
序号错误的常见原因:
- 发送方软件Bug,序号递增逻辑写错了
- 总线丢帧,导致序号不连续
- 接收方处理太慢,漏掉了某些帧
举个例子:发送方发了CF1、CF2、CF3,但CF2在总线上丢了。接收方收到CF1后,等CF2,结果等来了CF3。接收方一看序号不对,直接报错,整个多帧传输失败。
协议规定:
接收方收到序号错误的连续帧,必须发送「流控制帧(FC)」,状态为「等待(WAIT)」,并丢弃当前多帧消息。发送方收到WAIT后,会重新发送整个多帧消息。
我个人习惯,在实现发送方时,会加一个序号校验的断言。每次发送前检查序号是否连续,如果发现不连续,直接打印错误日志。这样能快速定位软件Bug。
4.4 报文长度不匹配
报文长度不匹配,说白了就是接收方收到的数据总长度,和发送方声称的长度对不上。
多帧传输的第一帧(FF帧)里,会携带一个「数据长度」字段,告诉接收方总共有多少字节。接收方收到所有连续帧后,会计算实际收到的字节数。如果两者不一致,接收方就会认为传输出错。
长度不匹配的原因:
- 发送方填错了长度字段
- 连续帧丢帧,导致实际数据少了
- 接收方拼接逻辑有Bug,多算了或少算了字节
| 故障现象 | 可能原因 | 排查方法 |
|---|---|---|
| 接收方报「长度错误」 | FF帧的长度字段与实际数据不符 | 抓报文,对比FF帧的DLC和实际数据长度 |
| 接收方报「数据不完整」 | 连续帧丢帧 | 检查总线错误计数,看是否有丢帧 |
| 接收方报「多余数据」 | 接收方拼接逻辑多算了字节 | 检查接收方的数据缓冲区管理 |
我记得有一次,一个ECU在接收大数据时总是报长度错误。查了半天,发现是发送方在FF帧里填的长度是1000字节,但实际发送了1001字节。为什么?因为发送方在计算长度时,忘了把最后一个字节算进去。这种低级错误,说白了就是代码审查没做到位。
排查建议:
用CAN工具抓取完整的多帧传输过程,手动计算每一帧的数据长度,和FF帧声明的长度对比。如果发现不一致,问题大概率出在发送方。
4.5 综合排查思路
遇到网络层故障,我一般按这个顺序排查:
- 抓报文:用CAN工具抓取完整的通信过程
- 看时序:检查每一帧的发送和接收时间,看是否有超时
- 看序号:检查连续帧的序号是否连续
- 看长度:检查FF帧的长度字段和实际数据是否一致
- 看流控:检查FC帧是否正常发送,状态是否正确
你想想看,网络层其实就干三件事:拆包、发送、拼包。只要这三件事不出错,网络层就稳了。但实际项目中,这三件事往往因为各种原因出错。嗯,多积累经验,多抓报文分析,慢慢就能练出「火眼金睛」。
总结一下:
多帧传输超时,查时间参数和总线负载。
流控制帧丢失,查接收方软件和中断处理。
连续帧序号错误,查发送方序号逻辑和总线丢帧。
报文长度不匹配,查FF帧长度字段和实际数据。
网络层故障排查,说白了就是「抓报文、对协议、找差异」。只要你有耐心,没有查不出来的问题。