ISO 15765-2帧格式详解:单帧、首帧、流控帧、连续帧及多帧传输
发布时间:2026/10/21 7:13:32 锦皓数字建站

做车载网络诊断这些年我收到最多的求助不是CAN收发器坏了而是“诊断响应发不出去”或者“ECU收到请求不回”。查到最后十次有七八次都栽在ISO 15765-2的传输层封装上单帧、首帧、流控帧、连续帧这四种PDU的格式理解不到位帧一多就出岔子。这篇文章想把ISO 15765-2也就是AUTOSAR里CanTp模块要实现的那个协议的帧格式从头到尾讲透包括每种帧的字节布局、多帧传输时的流控机制、以及我在联调时踩过的一系列坑。无论你是在做UDS诊断、OBD排放还是刷写Bootloader理解这套帧格式都能让你少熬好几个通宵。1. 为什么搞懂这四种帧格式是诊断开发的基本功1.1 标准CAN数据场只有8字节根本装不下一整条诊断数据先算一笔账。标准CAN帧Classical CAN的数据场最多8个字节而一条诊断报文往往不止8字节读VIN返回17字节读故障码可能要几十上百字节复杂ECU的刷写动辄几千字节。8字节的“集装箱”装不下大件货物协议就得设计一套“拆包-运输-拼包”的规则ISO 15765-2干的就是这件事。这套规则其实很朴素小于等于7字节的直接用一帧发出去这叫单帧超过7字节就先发一个首帧告诉接收方“我这次总共要发多少字节”接收方看情况回一个流控帧告诉发送方“你现在可以发多少、每次间隔多久”然后发送方用多个连续帧按顺序把剩余数据送完。很多人刚开始学诊断拿到Trace只看CAN ID和data第一反应是“为什么ECU回的数据长得不一样”。比如0x7E8这条ID上一秒回的是03 62 F1 90下一秒变成10 14 62 F1 90……其实第一个是单帧第二个是首帧数据场首字节就是协议控制信息PCI剩下的才是真正的诊断数据。搞不清PCI就跟解不开密电码一样什么排查都无从谈起。1.2 在AUTOSAR协议栈里帧格式对应的是CanTp模块如果你做AUTOSAR开发ISO 15765-2这套逻辑通常落在CanTpCAN Transport Protocol模块里上面是PduR路由层再往上是DCM诊断层。DCM负责解析UDS服务PduR负责路由CanTp负责把超过单帧长度的PDU拆分、发送、重组。CanTp对外的接口、配置项比如N_PCI长度、帧类型、块大小、STmin全都基于ISO 15765-2的帧格式。这也意味着即便你不用完整AUTOSAR栈只是在单片机上自己写一个简易的诊断收发程序也需要按同样的帧格式收发。因为ECU固件、诊断仪、测试工具之间能对话靠的就是“每一种帧的数据字节布局完全一致”这个约定。格式哪怕错一个bit轻则一帧校验失败重则整个多帧传输被接收方直接中止。1.3 四种帧是一个完整的“运输系统”我习惯把这四种帧类比成快递运输单帧SF就是小包裹一个人直接扛走首帧FF是大件包裹的运单上面写着“总共有多少件”顺便带上第一批货流控帧FC是收件人回复调度中心的确认函“一次送几件、每两件之间至少隔多少分钟”连续帧CF就是按顺序赶来的一辆辆货车每辆车身上都印着序号方便收件人对齐顺序、发现丢件。这里注意一个重点多帧会话中通信双方不是平等的。发送方比如ECU回诊断响应时负责按协议拆包和发送接收方一般是诊断仪负责确认首帧、回流控帧、检查连续帧序号、重组数据。谁发起多帧、谁回流控取决于当前这条PDU是请求还是响应、长度是否超过7字节。把这段逻辑想清楚后接下来的字节级拆解就好懂多了。下面我按每一帧的结构逐字节拆包括高位、低位、长度、序号、流控参数这些细节正是最容易看走眼的地方。2. 四种帧的字节级拆解与编码规则先把四种帧的PCI布局汇总成一张表后面每一类再细讲帧类型PCI字节数首个PCI字节高4位关键字段标准CAN下最大用户数据单帧SF1字节0x0低4位表示数据长度7字节首帧FF2字节0x1低4位第二字节合成12位总长度首帧内最多6字节连续帧CF1字节0x2低4位是序号SN每帧最多7字节流控帧FC3字节0x3低4位是流控状态FS后接BS、STmin不含用户数据2.1 单帧SF一位PCI加最多7字节数据单帧的PCI只占1字节结构是高4位固定为0x0低4位表示后续数据长度取值范围0~7。所以一帧标准CAN帧里单帧能装载的最大用户数据就是7字节。例如诊断仪发起的请求“10 03”进入扩展诊断会话实际CAN报文数据场是03 10 03第一个03就是PCI表示后面有3个数据字节10 03才是UDS服务。这里有个很容易误解的点单帧PCI里的“长度”不包含PCI本身。如果低4位写0x03后面只允许再跟3个字节写0x07后面跟7个字节。有的初学者会把整个8字节都当成数据把CAN帧data[0]也当服务数据来解结果解析出来的UDS服务号全是错的。单帧是最安稳的一帧不涉及流控也不需要接收方确认。接收方读到一个0x0X开头的帧直接取低4位长度再把后面的数据交给上层解析即可。唯一要留意的是如果低4位长度写0表示这是一条没有数据内容的空PDU正常诊断中很少见到但协议栈要能容忍不能崩。2.2 首帧FF总共多少数据先交代清楚当待发送数据超过7字节发送方就不能用单帧了必须先发一个首帧。首帧的PCI占2字节第一个字节的高4位固定是0x1低4位与第二个字节组合成一个12位的长度值最大可以表示4095字节。也就是说ISO 15765-2在标准CAN下最多支持一条诊断PDU按4095字节来拆。因为PCI占了2字节首帧能附带的数据只有6字节。它会在发出首帧的同时把整条PDU的前6个字节一起带上这样接收方不用等收齐所有连续帧才拿到第一个字节效率会高一些。举例如果ECU要回一条20字节的响应首帧第一个字节为0x10第二个字节为0x140x10的高4位1表示FF低4位1与0x14合并为0x01420后面的6个字节就是响应的前6字节。看到0x10开头的帧接收方就知道“接下来会有一次多帧传输”并且马上能算出总共还差多少字节。这个“总长度”是后续所有数据场里的用户数据字节数不包含FF的两个PCI字节也不包含后续每个CF的PCI字节。2.3 流控帧FC接收方把握传输节奏首帧发出后发送方不能自顾自地继续发连续帧要等接收方回一个流控帧。流控帧的PCI固定3字节第一个字节高4位是0x3低4位是流控状态FS0表示继续发送CTS1表示等待WT2表示溢出中止OVFLW第二个字节是块大小BlockSizeBS第三个字节是最小间隔时间STmin。为什么必须等流控因为接收方可能正在处理别的事情缓冲区也可能不够。比如ECU一边刷写一边回数据缓冲区只剩几十字节它就在流控帧里告诉诊断仪“一次最多发这么多字节每帧至少隔多少毫秒”。发送方照做就不会把接收方的缓冲区冲爆。值得说明的是BS0是一种特殊情况表示不限定块大小你把所有连续帧一口气发完我照单全收。但这并不意味着可以毫不停顿地连发STmin仍然生效。STmin通常填0x00~0x7F对应0~127毫秒0x80~0xF0区间是微秒级扩展编码实际量产ECU用得少绝大多数工具和ECU默认填毫秒值就够了。2.4 连续帧CF按序号接力最后一段不用满7字节接收方返回CTS之后发送方开始发连续帧。每个连续帧的PCI占1字节高4位固定是0x2低4位是序号SN取值范围0~15循环使用。第一个连续帧的SN必须是0也就是PCI为0x20第二个是0x21以此类推走到0x2F之后下一个回到0x20。接收方会严格检查SN是否按预期递增一旦发现跳号就会判定这一条多帧PDU损坏。连续帧每帧最多带7字节数据比首帧多1字节因为只有1字节PCI。如果PDU总长度不是7的倍数那么最后一帧自然不满7字节这是正常的。接收方在收满FF里声明的总长度后就不再等后续帧了。很多初级开发者看到最后一帧不足7字节会怀疑是不是丢数据实际上接收方要看的不是“每帧都满”而是“总的到达字节数等于FF里申报的长度”。SN还有一个隐藏用途配合超时时间做丢帧检测。接收方收到CF后启动定时器如果超过N_Cr还没等到下一帧就认为发送方出了故障可以停止等待或向上层报错。3. 多帧传输的协商机制与关键参数计算3.1 流控帧的三个参数分别管什么多帧传输能不能稳定跑通很大程度取决于流控帧里BS和STmin填的数值。BS决定“每发多少个连续帧后发送方必须停下来等下一次流控”STmin决定“连续帧之间的最小发送间隔”。两者不是相乘是叠加约束。举例来说BS3、STmin10ms意味着连续发3个CF帧与帧之间至少隔10ms发完第3个后停下来等接收方回下一个FC。如果BS0整个传输过程中不再有分组门禁只保留STmin的间隔限制。这里面的“行为主体”容易搞混STmin约束的是发送方每发完一帧后必须等待的最短时间不是最大时间。发送方可以比STmin更慢但绝不能更快。BS约束的是连续帧的分组边界接收方在每收满BS个CF后才回一个FC。假如接收方一直不回FC发送方会按N_Bs超时停止而不是傻等。我在项目里见过不少工程师把STmin理解成“接收方处理数据需要的时间”或者“接收方的响应时间”其实都不准确。STmin本质上是给接收方留出逐帧处理的时间。接收方如果处理得快就把STmin填小处理得慢就填大一点。同理BS填小可以降低接收方每次突发处理的压力但会增加额外的流控往返总时间变长。3.2 发送方和接收方各自需要维护的状态做协议栈实现时最好不要边发边想“下一步怎么办”而是把多帧传输定义成一个状态机。发送方至少要有空闲态、等待首帧后流控态、发送连续帧态、等待块流控态接收方至少要有空闲态、等待连续帧态、组装完整态。整个链路是这样走的发送方发FF后进入等待流控的时间窗口N_Bs。收到FC后检查FSCTS就按BS和STmin发送CFWAIT就继续等但不能无限等超过N_Bs或N_Cr要中止OVFLW直接放弃整条传输。接收方收到FF后记录总长度发回FC然后等着接收CF。每收一个CF检查SN是否连续并把数据拼进缓冲区。当累计数据长度等于FF声明的总长度时这条PDU重组完成交给上层如果SN跳号或者等待超时接收方要么发OVFLW主动终止要么直接丢弃。这两套状态机看起来简单但很多疑难杂症就出在状态没有正确复位比如某次多帧传输被中止后发送方还停留在“等待流控”状态下一次新的FF来了它没反应形成“ECU假死”的效果。排查这种问题先看协议栈的状态机复位逻辑往往比改参数更有效。3.3 一次完整多帧传输的逐拍推演我拿一个贴近日常的例子读取VIN。诊断仪发“22 F1 90”请求读取VIN标识响应里除了服务号和DID之外还有17字节的VIN数据整条响应正好20字节。这条链路大概这样走诊断仪发单帧请求03 22 F1 90。PCI03后面3字节是UDS服务。ECU回首帧10 14 62 F1 90 AA BB CC。PCI两字节表示总长0x01420先带6字节其中62 F1 90是正响应和DIDAA BB CC是VIN前3字节占位。诊断仪回流控帧30 00 14。FS0表示CTSBS0表示不限制块STmin20ms。ECU发第一个连续帧20 D1 D2 D3 D4 D5 D6 D7SN0带7字节。ECU发第二个连续帧21 D8 D9 DA DB DC DD DESN1带最后7字节。诊断仪累计收到67720字节重组完成交给UDS层解析得到完整的“62 F1 90 17字节VIN”。这个例子里FF后等FCFC后按20ms间隔发两个CF。BS0所以省去了块间流控。如果BS改成1那么每发一个CF都要等接收方再回一次FC时间会明显变长但接收方的缓冲压力也小低速ECU更喜欢这种配置。这类推演在排查“响应太慢”时非常有用你可以在Trace里数一数一次多帧传输中出现了几次FC往返每次等待了多久。如果发现BS设成了0x01一次VIN读取可能要来回六七个报文响应时间自然被拖慢。合理调大BS或者改成BS0响应时间立刻改善。4. 实战拆包把一段CAN报文还原成完整诊断响应4.1 动手之前先确认三件事在实际项目中我们拿到的往往不是干净的协议数据而是带各种干扰的CAN报文。所以我拿到一段Trace不会急着逐帧解析先确认三件事。第一确认寻址方式。如果CAN ID是传统的11位ID标准帧PCI从数据场第一个字节开始如果采用扩展寻址数据场第一个字节是子地址比如常见的0x7FPCI就要从第二个字节看起。很多解析工具里如果把扩展地址定义成报文里的某个信号解析时忘了偏移1字节整段数据都会错位。第二确认ECU回的是物理寻址响应还是功能寻址响应。功能寻址比如向0x7DF发请求时多个ECU都可能在同一个CAN ID上同时回单帧这本身没问题但多帧响应在功能寻址下极易产生流控帧冲突所以绝大多数多帧响应都走物理寻址。第三确认当前CAN网络的帧类型。标准CAN数据场8字节CAN FD可能更长。如果是CAN FDSF/FF能装的数据量会大于经典CAN但ISO 15765-2的PCI头部结构不变只是“每帧能装多少数据”变了。4.2 逐帧解析的完整操作假设总线调试工具窗口里有这样一串报文0x7E0是诊断仪请求ID0x7E8是ECU响应ID0x7E003 22 F1 900x7E810 14 62 F1 90 AA BB CC0x7E030 00 140x7E820 D1 D2 D3 D4 D5 D6 D70x7E821 D8 D9 DA DB DC DD DE我解析的步骤是固定的。先看0x7E0那帧。data[0]0x03高4位0x0是单帧低4位长度3数据是22 F1 90。这是UDS的ReadDataByIdentifier请求DID是0xF190。再看0x7E8的首帧。data[0]0x10高4位0x1是FFdata[1]0x14于是总长度0x01420字节。数据从data[2]开始62 F1 90 AA BB CC共6字节。0x62是ReadDataByIdentifier的正响应DID0xF190后面AA BB CC是VIN前3字节的占位。然后诊断仪回0x30 00 14。data[0]0x30FS0允许发BS0不分组STmin20ms。继续看连续帧。第一帧data[0]0x20高4位0x2是CFSN0后面D1~D7共7字节第二帧data[0]0x21SN1后面D8~DE共7字节。VIN剩余14字节正好补齐。整条响应就是62 F1 90 加上17字节VIN数据总长20字节和FF声明一致。这样拆下来你就能确认端到端的数据链路是通的也能精确判断问题出在哪一段。4.3 用工具核对和反向验证手工拆包适合练手和排查但平时联调我建议配合总线工具里的协议解码功能。大多数专业CAN调试工具都内置ISO 15765-2解码你只需要把收发报文的CAN ID配置成诊断ID工具会自动把FF/CF拼成完整数据。如果工具显示出来的多帧数据不完整多半是寻址方式配置错了或者CAN ID过滤范围不对。反向验证也有一个实用技巧如果工具解码结果和你手工拆的不一致别急着怀疑工具。先把原始数据按上面的步骤自己拆一遍数一下FF里声明的总长度是否等于收到的所有CF数据长度之和。很多时候工具解码失败是因为FF的长度字段和实际发送长度对不上接收端的协议栈不会装傻直接把整条PDU丢了。我还习惯在主流的总线分析工具里写一个小解析器按CAN ID分类统计每一条多帧传输里CF数量是否符合预期、SN是否连续、FC延时是否超过了N_Bs。写这个解析器时你会发现你对四种帧格式的理解会被迫精确到一个bit很多隐藏问题就是在写解析器的过程中暴露的。5. 在AUTOSAR配置和实车联调中踩过的坑5.1 连续帧SN“开头不对”和回绕问题第一次做ECU多帧响应时我按“习惯”把第一个连续帧的SN写成了1结果诊断仪一直在那等下一帧最后超时。查过标准才发现FF后的第一个连续帧SN必须是0也就是说data[0]0x20而不是0x21。一些自研协议栈对SN的起始值并不在意收到0x21开头也照收但正规诊断仪和测试工具会严格校验SN只要不在预期位置整条多帧传输就被判定无效。另一个容易踩的是SN回绕。当连续帧超过15个SN会从0x2F回绕到0x20。接收方必须有“预期SN当前SN10x0F”这样的逻辑不能简单用大于、小于判断。我就见过同事在纯C代码里用if(SN lastSN)判断连续性传输超过16帧后直接状态错乱。排查SN问题有个很有效的办法在测试工具里开故障注入人为篡改下一个CF的SN看接收方是否能立即识别并中止。如果接收方毫无反应说明它的SN检查逻辑有洞。5.2 BS、STmin配错引发响应超时某项目里ECU响应总在“读多字节DID”时超时。抓包发现流控帧里的STmin0x00发送方几乎是背靠背发CF而接收方缓冲区有限后面几帧被CAN控制器直接丢弃接收方等待N_Cr超时后中止传输上层表现就是“诊断响应超时”。这事的根子是STmin配置得太激进。有人可能觉得零延迟不是更快吗但在高负载总线上诊断仪连发多个CF时ECU的中断处理、协议栈逐帧复制、上层解析未必能跟上。把STmin从0x00改成0x0A10ms后这个毛病就消失了。同理BS如果设得太小比如0x01每次发一个CF都要等一个FC来回握手的时间会显著拖慢响应设成0x00无限块时又可能让某些低速接收方缓冲溢出。所以BS和STmin本质是一对trade-off必须根据接收方的缓冲能力和总线负载去配不存在一个万能值。我现在的经验是默认先配BS0、STmin0x0A~0x1410~20ms让链路跑通如果总线上还有其他高优先级报文或接收缓冲较小再适当加大STmin或减小BS。这个组合在绝大多数8字节标准CAN诊断场景里都很稳。5.3 扩展寻址和功能寻址带来的“隐形偏移”在部分车内网络上诊断报文用扩展寻址数据场第一个字节是子地址。有些ECU的CanTp配置里设了PCI偏移但诊断仪侧的解析配置没有同步于是工具在解析多帧响应时把所有字节都往左偏移了一位整条数据全错。这种问题在表面上和协议栈本身没有关系排查时最容易走弯路。我的建议是先看数据场第一个字节是不是固定的扩展地址如果是说明要走扩展寻址解析PCI一律从data[1]开始。流控帧也一样扩展寻址下流控帧的数据场会多占一个字节BS和STmin对应的字节位置要右移。功能寻址则是另一个坑。诊断仪向0x7DF发功能寻址请求多个ECU同时回单帧各说各话还好但如果有ECU需要回多帧响应多个ECU同时发FF诊断仪侧的流控帧根本无法确认发给谁。我遇到过功能寻址请求“读软件版本号”几个ECU同时回多帧总线直接被冲乱最后改成物理寻址才消停。所以在项目里尽量让所有多帧响应走物理寻址。5.4 我的自查清单和调试节奏踩过这么多坑后我总结了一份自查清单每次多帧传输出问题就按顺序过一遍先确认是不是数据长度超了7字节却误用了单帧格式。确认FF长度字段是否等于PDU总长度不包含PCI本身。确认FC的FS值0继续、1等待、2中止别把0x32当成继续。确认第一个CF的SN是0x20后续每个CF的SN连续递增。确认CF数量是否足够最后一段不满7字节是正常现象。确认BS、STmin和接收方缓冲能力是否匹配必要时抓Trace量FC间隔。确认寻址方式标准寻址看data[0]扩展寻址从data[1]开始。确认多帧会话是否长时间无响应检查状态机是否复位、N_Bs和N_Cr是否被触发。我调试时习惯用最小的场景先自测故意发一条刚好8字节的PDU再发一条刚好9字节的PDU逼它走FF加一个CF的路径看协议栈能不能拼完整。这种边界测试比直接上复杂的几十字节刷写流程更能快速暴露问题。往后再遇到“ECU不回响应”或者“诊断仪收不到多帧数据”先把这8条过一遍大概率能在十分钟内定位到是格式问题、参数问题还是配置问题。这套方法帮我不止一次把疑难杂症变成了已知问题也希望对你排查自己的项目有所帮助。最后再补一句个人心得多帧传输不怕数据大就怕状态乱。只要时刻记得“首帧报总长、流控定节奏、连续帧按序号”ISO 15765-2这套协议再怎么变你都有底气去拆解它。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。