拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

UDS多帧传输避坑指南:STmin与BS参数详解及调试技巧

UDS多帧传输避坑指南:STmin与BS参数详解及调试技巧 1. 为什么多帧传输是UDS诊断里最容易翻车的一环搞过UDS诊断的人都有一个共识单帧收发的诊断服务比如会话控制、读取故障码基本不会出问题真正让人抓耳挠腮的永远是那些数据长度超过7个字节、必须走多帧传输的场景。典型的就是UDS刷写流程里的RequestDownload、TransferData还有31服务例程控制里那些需要下发大块配置数据的场景。你拿CANoe或者类似工具一跑发现请求发出去了ECU就是不回或者回了个否定响应然后你盯着trace窗口看半天不知道问题出在哪儿。这篇文章就是冲着这个问题来的。我会把UDS多帧传输的报文结构从头拆一遍重点讲清楚首帧、连续帧、流控帧各自的字段含义然后把STmin和BS这两个流控参数掰开揉碎地讲——它们分别控制什么、怎么配、配错了会出什么现象。最后我会给出一套实际调试中总结出来的排查思路和避坑清单都是踩过坑之后才搞明白的东西。适合谁看如果你正在做UDS协议栈的开发或者测试尤其是涉及到刷写流程uds刷写详细流程或者大数据块传输的场景这篇文章应该能帮你省下不少抓包分析的时间。如果你刚开始接触uds诊断协议对多帧传输还没有直观感受也没关系我会尽量用生活化的类比把机制讲清楚。先给一个最直观的类比。UDS多帧传输就像你搬家你有一堆东西要运到新房子数据太长一帧装不下你得先跟搬家公司说“我有30箱东西要运”首帧告诉对方总共有多少搬家公司回你“行你每次搬5箱过来搬完一车等我信号再搬下一车”流控帧BS5STmin等待时间然后你就一车一车地搬连续帧直到搬完。这个过程中BS和STmin就是搬家公司给你的节奏控制参数。节奏不对要么你搬太快对方来不及卸货缓冲区溢出要么你搬太慢效率极低传输超时。2. UDS多帧传输的报文结构拆解2.1 单帧与多帧的分界线在哪里UDS协议在CAN总线上的传输受限于经典CAN帧的数据场只有8个字节。这8个字节里第一个字节被用作协议控制信息PCI剩下的7个字节才是有效数据。所以当你要传输的诊断请求或响应数据超过7个字节时就必须走多帧传输。这里有一个容易混淆的点ISO-TPISO 15765-2是负责传输层分帧和重组协议的UDSISO 14229是应用层协议。多帧传输的机制是ISO-TP定义的UDS只是使用者。所以你在看报文的时候PCI字节的解析规则是ISO-TP的规则不是UDS的规则。这个区分很重要因为很多排查思路的起点就是先确认ISO-TP层有没有正常工作。单帧的PCI格式很简单高4位是帧类型0表示单帧低4位是数据长度SF_DL。比如0x03 22 F1 90第一个字节0x03表示这是一个单帧后面有3个字节的有效数据22 F1 90即读取VIN码的请求。多帧就复杂一些了分为首帧First FrameFF、连续帧Consecutive FrameCF和流控帧Flow ControlFC三种类型。帧类型由PCI字节的高4位标识1表示首帧2表示连续帧3表示流控帧。2.2 首帧的报文结构告诉对方“我要发多少”首帧的PCI占用两个字节。第一个字节的高4位是1表示首帧低4位和第二个字节一起组成一个12位的长度字段FF_DL表示整个数据的总字节数。12位能表示的最大值是4095也就是说标准寻址方式下ISO-TP单次传输的最大数据长度是4095字节。首帧的数据场里PCI占2个字节剩下6个字节放实际数据。举个例子假设你要通过TransferData传输100个字节的数据首帧大概是这样的首帧: 10 64 [data1] [data2] [data3] [data4] [data5] [data6]其中0x10的高4位是1首帧低4位是00x64是100的十六进制。合起来0x1064就是长度字段表示总共有100个字节要传输。后面6个字节是数据的前6个字节。这里有一个实际调试中经常遇到的坑长度字段的计算。FF_DL表示的是整个UDS消息的长度包括UDS的服务标识符SID和数据参数但不包括PCI字节本身。很多人在计算长度的时候容易把PCI字节也算进去导致ECU收到的长度和实际不符直接回否定响应。2.3 连续帧的报文结构一帧一帧往下搬连续帧的PCI只占1个字节。高4位是2表示连续帧低4位是一个序列号SNSequence Number。序列号从1开始每发一帧加1到15之后回绕到0继续。注意首帧的序列号默认是0所以第一个连续帧的序列号是1。连续帧的数据场里PCI占1个字节剩下7个字节全部是有效数据。所以如果你要传输100个字节首帧带了6个字节剩下94个字节需要连续帧来传。94除以7等于13余3也就是说需要14个连续帧最后一个连续帧只带3个字节的有效数据。序列号的作用是让接收方能够检测是否有帧丢失或乱序。如果接收方期待的序列号是5但收到的是6说明中间丢了一帧接收方会中止接收并报错。这个机制在多帧传输中非常关键因为CAN总线上的干扰或者缓冲区溢出都可能导致丢帧。2.4 流控帧的报文结构接收方给发送方定规矩流控帧是接收方发给发送方的用来控制发送节奏。它的PCI占用三个字节结构如下第一个字节高4位是3表示流控帧低4位是流状态FSFlow Status。FS有三个值0CTSContinue To Send继续发送接收方准备好了1WAIT等待接收方暂时没准备好发送方需要等下一个流控帧2OVFLWOverflow溢出接收方的缓冲区不够无法接收这么多数据第二个字节是块大小BSBlock Size告诉发送方在收到下一个流控帧之前可以连续发多少个连续帧。如果BS为0表示不需要再等流控帧发送方可以一直发到数据发完。第三个字节是最小分离时间STminSeparation Time minimum告诉发送方两个连续帧之间至少要间隔多长时间。单位通常是毫秒但也有一些特殊值需要特别注意后面会详细讲。流控帧的数据场里PCI占3个字节剩下5个字节可以放附加数据比如一些厂商自定义的信息但大多数情况下这5个字节填0或者忽略。3. STmin和BS这两个参数到底在控制什么3.1 BS一次连续发多少帧就要停下来等指令BS的全称是Block Size直译就是块大小。它的含义是发送方在收到一个流控帧之后最多可以连续发送多少个连续帧然后就必须停下来等接收方发下一个流控帧。为什么需要这个机制因为接收方的缓冲区大小是有限的。如果发送方不管不顾地一直发接收方的缓冲区满了之后就会丢帧。BS就是接收方告诉发送方“我的缓冲区一次能处理这么多帧你发完这些就停一下等我处理完了再继续。”BS的取值逻辑很直接BS 0表示不需要流控发送方可以连续发送所有连续帧直到数据发完。这通常用在接收方缓冲区足够大、或者数据量本身不大的场景。BS NN 0发送方每发N个连续帧就要等接收方发下一个流控帧才能继续。实际配置中BS的值取决于ECU的接收缓冲区大小和诊断仪的处理能力。我见过一些ECU的BS配置为8也见过配置为16的。如果BS配得太大ECU缓冲区不够就会丢帧如果BS配得太小传输效率会明显下降因为每发几帧就要等一个流控帧来回的握手时间会拖慢整体传输速度。这里有一个容易被忽略的点BS是在流控帧里由接收方动态指定的不是发送方自己决定的。也就是说诊断仪作为发送方它不能自己决定一次发多少帧而是要听ECU的。但在实际实现中有些诊断仪的协议栈会忽略ECU指定的BS自己按固定值发送这就可能导致兼容性问题。3.2 STmin两帧之间至少要隔多久STmin的全称是Separation Time minimum即最小分离时间。它规定的是发送方在发送两个连续帧之间必须等待的最短时间。注意是“最短时间”也就是说发送方可以等更久但不能比这个时间短。为什么需要STmin因为接收方处理每一帧都需要时间。如果发送方发得太快接收方的CPU还没来得及把上一帧的数据从CAN控制器读到应用层缓冲区下一帧就来了就会导致数据覆盖或者丢失。STmin就是给接收方留出的处理时间。STmin的单位和取值有一些细节需要注意。标准ISO 15765-2定义的STmin取值范围是0x00到0x7F单位是毫秒。但还有两个特殊区间0x80到0xF0保留值不使用0xF1到0xF9表示100微秒到900微秒具体是值 - 0xF0× 100微秒。比如0xF1表示100微秒0xF5表示500微秒。0xFA到0xFF保留值不使用这个微秒级的定义在实际中很少用到因为大多数CAN总线的通信周期和ECU的处理能力都达不到微秒级的精度。但如果你在调试一个高性能的ECU发现它返回的STmin是0xF1不要惊讶它就是在告诉你“我处理很快你隔100微秒就可以发下一帧”。STmin配得太大传输效率低配得太小接收方处理不过来。实际中常见的STmin值是1ms到5ms。有些ECU会返回0ms表示不需要额外等待但这通常要求发送方和接收方的处理速度都足够快。3.3 BS和STmin的配合关系BS和STmin是配合工作的。BS控制的是“发多少帧停一次”STmin控制的是“每帧之间隔多久”。两者共同决定了多帧传输的整体节奏。举个具体的例子。假设你要传输1000个字节的数据首帧带了6个字节剩下994个字节需要连续帧传输。每个连续帧带7个字节994除以7等于142个连续帧。如果ECU返回的流控帧是BS10STmin2ms那么传输过程是这样的发送方发首帧接收方回流控帧BS10STmin2ms发送方连续发10个连续帧每帧之间间隔至少2ms发送方停下来等流控帧接收方处理完这10帧后再发一个流控帧重复步骤3-5直到142帧全部发完整个传输过程中流控帧会发送ceil(142/10) 15次最后一次可能不满10帧。每次流控帧的往返时间加上10帧的传输时间就是这一块数据的传输耗时。如果STmin配得太大或者BS配得太小传输时间会显著增加。在实际的UDS刷写场景中传输时间是一个敏感指标。如果传输太慢可能会触发ECU的刷写超时P2Server或者S3Server超时导致刷写失败。所以BS和STmin的配置需要在可靠性和效率之间找平衡。4. 多帧传输的完整交互流程与实操要点4.1 一次典型的多帧传输时序我把一次完整的多帧传输交互拆成几个阶段方便你对照trace窗口看。阶段一发送方发首帧。发送方把要传输的数据总长度和第一部分数据放在首帧里发出去。此时发送方进入等待状态等接收方的流控帧。阶段二接收方回流控帧。接收方收到首帧后解析出总长度检查自己的缓冲区是否能容纳。如果能就回一个CTS流控帧带上BS和STmin。如果不能就回OVFLW。如果暂时不能但稍后可以就回WAIT。阶段三发送方发连续帧。发送方收到CTS后按照BS和STmin的约束开始发送连续帧。每发完BS个连续帧就停下来等下一个流控帧。阶段四接收方收完所有帧。接收方收齐所有连续帧后进行数据重组然后交给上层UDS协议栈处理。如果是诊断请求ECU会执行相应的服务并返回响应如果是刷写数据ECU会写入Flash。阶段五接收方发响应如果需要。如果这是一个需要响应的UDS服务ECU会按照同样的多帧传输机制把响应数据发回给诊断仪。此时角色互换ECU变成发送方诊断仪变成接收方。这里有一个实际调试中的经验很多人在排查多帧传输问题时只关注发送方向忽略了响应方向也可能出问题。比如诊断仪发请求的时候一切正常但ECU的响应数据太长需要多帧回传结果诊断仪的接收缓冲区配置不对导致响应收不全。所以排查的时候要两个方向都看。4.2 流控帧的WAIT状态处理WAIT状态是实际调试中比较容易忽略的一个点。当接收方回WAIT时发送方需要等待接收方发下一个流控帧而不是继续发送连续帧。但这里有一个超时机制如果发送方等太久通常是N_WFTmax次WAIT或者N_Cs超时就会中止传输。N_WFTmax是ISO-TP定义的一个参数表示最多允许接收方回多少次WAIT。超过这个次数发送方就认为接收方出了问题中止传输。N_WFTmax的典型值是5或者10具体取决于协议栈的配置。在实际中WAIT状态通常出现在ECU正在处理其他高优先级任务、暂时无法接收诊断数据的时候。比如ECU正在执行Flash擦除操作CPU负载很高就会先回WAIT让诊断仪等一等。如果你的诊断仪协议栈没有正确处理WAIT状态可能会直接报错或者超时。4.3 序列号回绕的处理连续帧的序列号是4位的范围从0到15。首帧的序列号固定为0第一个连续帧的序列号是1依次递增到15之后回绕到0然后继续1、2、3……这个回绕机制在传输大量数据时一定会遇到。比如你要传1000个字节需要142个连续帧序列号会回绕8次多。接收方在检查序列号时需要正确处理回绕不能简单地用“当前序列号等于上一个序列号加1”来判断而是要用模16的运算。我见过一些自己实现的协议栈在这里出问题序列号到了15之后下一个帧的序列号应该是0但代码里写的是16导致接收方认为序列号错误中止传输。这种问题在传输小数据量时不会暴露一旦数据量超过15帧就必现。4.4 实操中如何抓包分析多帧传输抓包分析是排查多帧传输问题的主要手段。我用CANoe或者类似的工具抓包时通常会关注以下几个点第一看首帧的长度字段是否正确。把FF_DL解析出来和你实际要发送的数据长度对比。如果不一致说明发送方的协议栈在计算长度时出了问题。第二看流控帧的BS和STmin值。这两个值决定了后续连续帧的发送节奏。如果BS0说明接收方不需要流控如果BS是一个很小的值比如1或2说明接收方缓冲区很小传输效率会很低。第三看连续帧的序列号是否连续。如果发现序列号跳变说明中间有帧丢失。这时候要检查CAN总线的负载率、发送方的发送间隔是否满足STmin要求、接收方的缓冲区是否溢出。第四看时间间隔。两个连续帧之间的时间间隔应该大于等于STmin。如果小于STmin说明发送方没有遵守流控帧的约束接收方可能会丢帧。第五看是否有WAIT流控帧。如果有说明接收方处理不过来需要检查ECU的CPU负载或者缓冲区配置。5. 常见问题与排查技巧实录5.1 常见问题速查表现象可能原因排查方向发送首帧后无响应ECU不支持该服务、会话模式不对、寻址方式不对检查会话状态、确认物理/功能寻址、看ECU是否有任何响应收到OVFLW流控帧ECU接收缓冲区不足、数据长度超过ECU支持的最大值减小单次传输的数据量、检查ECU的缓冲区配置连续帧发到一半停止序列号错误、STmin不满足、BS配置不匹配抓包看序列号和时间间隔、检查流控帧的BS值传输超时STmin太大、BS太小导致握手次数过多、ECU处理慢优化STmin和BS配置、检查ECU的P2超时参数响应数据收不全诊断仪接收缓冲区不足、未正确处理多帧响应检查诊断仪的ISO-TP接收配置、确认缓冲区大小序列号回绕后报错协议栈序列号处理未做模16运算检查协议栈代码的序列号递增逻辑5.2 避坑技巧一不要忽略寻址方式对多帧传输的影响ISO-TP支持多种寻址方式标准寻址、扩展寻址、混合寻址。不同的寻址方式下PCI字节的位置和可用数据长度是不一样的。标准寻址下PCI在第一个字节数据从第二个字节开始每帧最多7个字节的有效数据。扩展寻址下第一个字节是地址扩展AE第二个字节才是PCI数据从第三个字节开始每帧最多6个字节的有效数据。混合寻址下第一个字节是地址扩展第二个字节是PCI但地址扩展的含义不同。如果你在配置诊断仪时选错了寻址方式PCI解析就会完全错位。比如ECU用的是扩展寻址但诊断仪按标准寻址解析就会把地址扩展字节当成PCI导致帧类型判断错误。这种问题在跨厂商的ECU调试中很常见因为不同厂商对寻址方式的选择不一样。5.3 避坑技巧二STmin的单位陷阱前面提到过STmin的标准单位是毫秒但0xF1到0xF9表示100微秒到900微秒。这个细节在实际中很容易被忽略。我遇到过一个案例ECU返回的STmin是0xF1诊断仪的协议栈没有正确处理这个特殊值直接把它当成241毫秒0xF1 241结果每帧之间等了241毫秒传输1000个字节花了30多秒直接触发了刷写超时。后来把协议栈里STmin的解析逻辑改成支持微秒级问题就解决了。所以你在实现或配置协议栈时一定要确认STmin的解析逻辑是否覆盖了0xF1到0xF9这个区间。如果ECU返回的是这个区间的值而你的协议栈不支持要么会等太久要么会报错。5.4 避坑技巧三BS0不一定意味着可以全速发送BS0表示接收方不需要流控发送方可以连续发送所有连续帧。但这并不意味着发送方可以无视STmin。即使BS0STmin仍然有效发送方仍然需要在每帧之间等待至少STmin的时间。有些协议栈的实现里BS0时会把STmin也忽略掉直接以最快的速度发送。这在接收方处理速度足够快的情况下可能没问题但如果接收方处理不过来就会丢帧。所以正确的做法是BS0时仍然遵守STmin的约束。5.5 避坑技巧四注意N_As和N_Ar超时ISO-TP定义了几个网络层超时参数其中N_As是发送方等待流控帧的超时时间N_Ar是接收方等待连续帧的超时时间。这两个超时参数如果配置不当会导致多帧传输在等待阶段就失败。N_As的典型值是1000毫秒也就是说发送方发了首帧之后最多等1000毫秒就要收到流控帧否则就中止传输。N_Ar的典型值也是1000毫秒接收方在发了流控帧之后最多等1000毫秒就要收到下一个连续帧。在实际中如果ECU的CPU负载很高处理首帧的时间可能超过1000毫秒这时候就需要适当增大N_As。但增大超时时间也会拖慢整体传输速度所以需要在可靠性和效率之间权衡。5.6 避坑技巧五多帧传输与UDS服务层超时的关系UDS应用层有自己的超时参数P2Server是ECU收到请求后开始响应的时间P2StarServer是ECU发送了否定响应后再次响应的时间。这些超时参数和多帧传输的耗时是有关联的。如果多帧传输耗时太长超过了P2Server的超时时间ECU可能会认为诊断仪已经放弃了从而中止响应。所以在配置STmin和BS时要估算一下整体传输时间确保不会触发UDS层的超时。估算方法很简单总传输时间约等于连续帧数量 / BS×流控帧往返时间 BS × STmin。流控帧往返时间取决于CAN总线的通信速率和ECU的处理速度通常可以按几毫秒到几十毫秒估算。如果算出来的总传输时间接近或超过P2Server的超时值就需要调整BS或STmin。6. 从协议栈源码角度看多帧传输的实现要点如果你是在做uds协议栈源码的开发或者移植有几个实现层面的点需要特别注意。首先是缓冲区的管理。发送方需要维护一个发送缓冲区存放待发送的完整数据接收方需要维护一个接收缓冲区用于重组收到的连续帧。缓冲区的大小要足够容纳最大的UDS消息长度。如果缓冲区太小大消息就会发送失败或者接收不全。其次是状态机的设计。ISO-TP的多帧传输本质上是一个状态机发送方有IDLE、WAIT_FC、SENDING_CF等状态接收方有IDLE、WAIT_CF、RECEIVING等状态。状态之间的转换条件要严格按协议实现特别是超时和错误处理的分支不能遗漏。第三是并发处理。在实际的ECU中诊断通信可能和其他任务并发执行。如果ISO-TP的状态机没有做好并发保护可能会出现数据竞争或者状态错乱。比如发送方正在发连续帧的时候上层又下发了新的诊断请求这时候需要正确处理请求的排队或者拒绝。第四是错误恢复。多帧传输过程中可能出现各种错误流控帧超时、连续帧丢失、序列号错误、缓冲区溢出等。协议栈需要能够检测这些错误并采取适当的恢复措施比如重传、中止传输、上报错误等。我在看一些开源的UDS协议栈实现时发现一个常见的缺陷对WAIT状态的处理不完整。有些实现收到WAIT流控帧后只是简单地等待但没有实现N_WFTmax的计数和超时判断导致如果接收方一直回WAIT发送方就会永远等下去。正确的做法是维护一个WAIT计数器超过N_WFTmax就中止传输并报错。7. 多帧传输的安全考量与防御思路多帧传输在UDS刷写流程中扮演着核心角色因为刷写数据动辄几十KB甚至几MB必须通过多帧传输来完成。这也意味着多帧传输的安全性直接关系到刷写流程的安全性。从防御的角度看有几个层面需要考虑。第一是流控帧的合法性校验。接收方在收到流控帧时需要校验FS值是否合法、BS和STmin是否在允许范围内。如果收到非法的流控帧应该拒绝并中止传输。第二是序列号的严格校验。接收方必须按模16的规则校验连续帧的序列号发现不连续立即中止。第三是传输超时的监控。无论是N_As、N_Ar还是N_Cs都需要严格监控防止恶意的或者异常的长等待导致资源占用。从攻击面的角度看多帧传输可能被利用来进行拒绝服务攻击。比如攻击者可以发送一个首帧声明一个很大的数据长度然后不发送连续帧导致接收方一直等待占用接收缓冲区和状态机资源。防御这种攻击的方法包括限制单次传输的最大数据长度、设置合理的接收超时、在超时后及时释放资源。另外在多帧传输的过程中数据的完整性和真实性也需要保护。虽然ISO-TP本身不提供加密和认证机制但在UDS刷写流程中通常会配合安全访问服务SecurityAccess0x27服务和刷写数据的校验机制如CRC校验、数字签名来确保数据不被篡改。多帧传输只是搬运数据数据本身的安全性需要上层机制来保证。8. 实际调试中的几个真实案例8.1 案例一BS配置过大导致刷写失败有一次在调试一个ECU的刷写流程时诊断仪发送TransferData请求ECU返回的流控帧是BS0STmin0。诊断仪按照BS0的规则连续发送所有连续帧中间不停顿。结果刷写到一半ECU返回了否定响应错误码是generalProgrammingFailure。抓包分析发现诊断仪发送连续帧的速度太快ECU的接收缓冲区溢出丢了几帧。但ECU的ISO-TP层没有检测到丢帧因为序列号检查有bug把不完整的数据交给了刷写模块刷写模块校验失败返回了错误。解决方案是修改ECU的流控帧配置把BS从0改成8STmin从0改成2ms。这样诊断仪每发8帧就停下来等流控帧给ECU留出处理时间。修改后刷写顺利完成。这个案例的教训是BS0虽然理论上可行但对接收方的处理能力要求很高。在实际工程中除非确认接收方处理速度足够快否则还是建议设置一个合理的BS值。8.2 案例二STmin单位解析错误导致传输超时另一个案例是关于STmin的。ECU返回的流控帧里STmin0xF1诊断仪的协议栈把它解析成了241毫秒。结果传输100个连续帧花了24秒多超过了刷写流程的P2超时ECU中止了刷写。排查的时候一开始怀疑是CAN总线负载问题后来仔细看流控帧的原始数据才发现STmin的值是0xF1。查ISO-TP标准才知道0xF1表示100微秒。修改协议栈的STmin解析逻辑后传输时间降到了几百毫秒刷写正常完成。这个案例的教训是STmin的取值区间不只是0x00到0x7F还有0xF1到0xF9这个微秒区间。实现协议栈时一定要完整覆盖。8.3 案例三序列号回绕处理错误还有一个案例是关于序列号回绕的。诊断仪在传输一个800字节的数据块时连续帧的序列号从1递增到15然后下一个帧的序列号应该是0但诊断仪的协议栈发的是16。ECU收到序列号16后认为序列号错误中止了传输。这个问题在传输小于15帧的数据时不会出现所以前期测试都没发现。直到传输大数据块时才暴露出来。修复方法很简单把序列号的递增逻辑改成模16运算。这个案例的教训是测试多帧传输时一定要用足够大的数据量覆盖序列号回绕的场景。如果只测试几十个字节的数据可能永远发现不了这个问题。9. 配置STmin和BS的实用建议基于上面的分析和案例我总结几条配置STmin和BS的实用建议。第一BS不要设为0除非你非常确定接收方的处理能力。建议从较小的值开始测试比如4或8然后逐步增大观察是否有丢帧或溢出。找到一个既能保证可靠性、又能保证效率的平衡点。第二STmin不要设为0除非接收方明确支持。建议从2ms到5ms开始测试。如果接收方返回的STmin是0但实际测试中发现丢帧可以尝试在发送方强制设置一个最小间隔。第三估算传输时间确保不超过UDS层的超时。传输时间的估算公式前面给过了实际中可以用抓包工具测量一下单次流控帧的往返时间然后代入公式计算。第四测试要覆盖边界场景。包括数据长度刚好等于7字节单帧边界、刚好等于8字节需要多帧的最小长度、超过4095字节超过标准寻址的最大长度、序列号回绕的场景、WAIT流控帧的场景。第五不同ECU的流控参数可能不同不要用一套配置打天下。在刷写不同厂商的ECU时要分别确认它们的流控帧配置必要时在诊断仪侧做适配。第六保留抓包日志。多帧传输的问题往往不是一次就能定位的保留完整的抓包日志方便反复分析。特别是对于偶发性的问题日志是唯一的线索。我在实际项目中养成了一个习惯每次刷写测试都保存完整的CAN日志并且在日志里标注关键节点首帧发送时间、流控帧接收时间、最后一个连续帧发送时间、响应接收时间。这样一旦出问题可以快速定位是哪个阶段耗时异常或者哪个帧出了问题。这个习惯帮我省了很多时间。有一次刷写偶发失败查了一周没找到原因后来翻之前的日志发现失败的那次传输中有一个流控帧的BS值是0而成功的那几次BS值都是8。进一步排查发现ECU在某些条件下会返回BS0而诊断仪对BS0的处理有bug。如果没有日志这个问题可能还要查更久。多帧传输的调试就是这样细节决定成败。STmin和BS这两个参数看起来简单但配置不当就会导致各种奇怪的问题。希望这篇文章能帮你在遇到类似问题时少走一些弯路。
返回列表