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

资讯详情

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

无车也能测网关:PCAN+J1939模拟发动机ECU的台架实战

无车也能测网关:PCAN+J1939模拟发动机ECU的台架实战 老实说刚接到VG710车载网关的测试任务时我坐在办公室工位上有点发愣——设备是有了可车子呢总不能从停车场强行拉一辆过来吧。后来和做车载网关、TBox、远程OTA的同行一聊才发现这不是我一个人遇到的事。项目排期已经压到眼前实车资源却一直排不上很多台架功能验证都被卡在“没车”这一步。而且这个场景特别典型办公室里常常堆着网关、电源、线束就差一台真车来输出OBD数据。我当时给出的解决方案就是标题里那套组合PCAN加上J1939协议模拟。用PCAN-USB适配器在CAN总线上主动“扮演”发动机ECU把那台不存在的发动机的报文制造出来再接VG710的OBD口。整个过程熟练之后真的只需要10分钟左右就能让网关在测试日志里稳定看到1500rpm的发动机转速。这篇文章就把我当时从零开始搭台架、算报文、调PCAN、再到写脚本自动化的全过程整理出来分享给正在被“无车可用”折磨的兄弟们。不管你是网关供应商的测试工程师、做TBox集成的软件同学还是刚接触车载CAN总线的嵌入式新手这套方法在办公桌上就能复现。1. 先理清思路把发动机ECU“搬”到办公桌上1.1 VG710在台架上需要哪些信号VG710这类车载网关本质上是一个连接车内部CAN总线、外部诊断口和云端平台的枢纽。它实时采集发动机、车身、底盘等节点的数据做协议转换后上报。要它在台架上“误以为”自己装在一台正常行驶的卡车上至少需要满足三个基本条件。第一是供电。网关一般需要常电KL30和点火信号KL15同时存在才能进入正常采集状态。很多网关的软件都写了“KL15掉线后进入休眠”如果只给常电它可能连CAN报文都不处理。所以无车台架上最常见的做法是用一台可调直流稳压电源模拟车载电源系统常电给12V或24V取决于车型平台点火信号再单独给一路12V或24V高电平。第二是CAN物理链路。网关的OBD口里面CAN_H和CAN_L两条线是它跟车辆ECU通讯的窗口对应OBD标准里通常说的6脚和14脚。我们需要把PCAN-USB适配器的CAN_H、CAN_L接到这两个脚上同时保证GND共地。没有共地的话CAN收发器会出现共模电压异常轻则报文丢帧重则烧毁接口芯片。第三是“像样的”CAN数据。网关拿到总线以后不会因为你只给它通了电就认为发动机在工作它需要看到发动机ECU周期性对外广播的J1939报文。只有在报文里读到转速、水温、扭矩等信号它才会在内部数据模型里把这些信号标记为“有效”之后才会上报到远程平台或者诊断工具。这三个条件补上办公桌上的VG710就已经具备“上车”的物理条件了。接下来唯一缺的就是让总线“热闹”起来——这一步由PCAN负责。1.2 为什么是PCAN J1939这套组合市面上CAN接口工具其实不少CANoe、CANalyzer、PCAN、USB-CAN分析仪甚至国内的周立功、创芯等各种盒子都有人用。我在这个测试里优先选PCAN背后有一些非常现实的原因。PCAN-USB系列在汽车电子行业的普及率很高原因是它的驱动和上位机软件非常稳定。PCAN-View作为官方免费工具不需要额外买授权装好驱动就能看到总线上每一帧报文也能直接发送自定义报文。对比CANoe动辄几万块的授权费用PCAN几百块的硬件成本在项目紧张时申请也更容易通过而且出差携带也方便。对于“办公室没车”这种需要快速搭环境的场景开箱即用的性质远比功能大而全更重要。协议方面选J1939则是由商用车和工程机械领域的实际情况决定的。VG710所涉及的车辆平台发动机ECU基本都走J1939协议尤其是转速、油耗、里程这类动力系统信号几乎被J1939的EEC1电子发动机控制器1等参数组覆盖。这是一套基于CAN 2.0B扩展帧的应用层协议物理层波特率通常固定为250kbps。想模拟一台商用车发动机绕不开J1939。所以PCAN解决的是“总线通道”问题J1939解决的是“报文语义”问题。两者一结合就等于我们能在办公桌上制造出一个“会说发动机语言”的虚拟ECU节点。1.3 一套最简测试链路长什么样整个无车测试链路的节点其实非常少我画一下逻辑拓扑你就明白了电脑运行PCAN-View或Python脚本产生J1939报文PCAN-USB适配器把电脑生成的报文转换成CAN差分信号发到总线上VG710网关从OBD口CAN网络接收报文解析出转速等信号并记录/上报稳压电源给VG710供常电和KL15点火信号。信号流向上PCAN这边是主动发送方扮演发动机ECUVG710是被动接收方。但在正常的整车上网关通常还会主动发送诊断请求报文这个请求PGN是EA00请求PGN如果PCAN那边没有回应该请求网关可能会认为该ECU不存在。不过在实际测试里EEC1这种广播型PGN是发动机自己主动发的不需要网关请求所以就算网关不发请求我们光靠周期广播也能让它读到转速。这个拓扑最大的优势是隔离了“被测试对象”和“车辆环境”。无车环境下被测对象是VG710车辆环境则由PCAN模拟出来因此任何故障都可以通过修改PCAN的发送内容来复现这在实车上反而很难做到。2. 准备工作硬件、驱动和J1939报文速算2.1 接线与上电按顺序来先把需要的东西列个清单这些在办公室很容易凑齐VG710网关模块一个PCAN-USB型号不限我用的是PCAN-USB Pro普通PCAN-USB也完全可以一台安装好PCAN驱动和PCAN-View的Windows电脑可调直流稳压电源至少两路输出常电和点火信号若干杜邦线或OBD连接线最好有OBD母座转接线测试方便很多120欧姆终端电阻至少准备一个。接线的顺序有讲究。我先接CAN总线再接电源的地线最后才给网关供电。避免先上电再插CAN线的原因很简单CAN收发器在带电状态下插拔容易因为触点的电势差产生电流冲击虽然不一定立刻损坏但长期下来会增加接口芯片失效的概率。实测中我见过不只一块PCAN就是因为反复热插拔最后通信不稳定。接线对应关系如下PCAN-USB的CAN_H接OBD母座的6脚CAN_L接14脚PCAN的地线接OBD的4脚或5脚。电源的正极接网关的常电脚点火信号再接一个正极到KL15脚。很多网关的供电接口与OBD座是分开的这种情况下你就要认真看规格书别把常电和点火接反一旦接反有些带防反接保护的模块还好没有保护的可能直接烧板子。终端电阻是很多人容易忽略的点。J1939和普通高速CAN一样要求总线两端各有一个120欧姆终端电阻。在只有PCAN和VG710两个节点的台架上如果你不确定网关内部是否带有终端电阻最稳妥的办法是在总线上手动接一个120欧姆电阻。没有终端电阻的总线波形反射会导致通信质量变差典型现象是发送成功率没问题但接收方偶发错误帧。上电顺序建议是先打开电源把常电加上等1-2秒后再把点火信号置高。这么做是为了让网关先完成上电初始化再检测到点火信号符合大多数车载电子设备的启动时序。如果常电和点火同时给有些网关的看门狗会误判异常复位。2.2 J1939报文里面的门道很多人一听J1939就头大其实把它拆开看无非就是“在28位CAN标识符上重新编码了一些字段”。SAE J1939基于CAN 2.0B的29位扩展帧关键字段有三个优先级、PGN参数组编号、源地址。PGN是理解J1939的核心。一个PGN代表一类参数组比如PGN 61444十六进制0xF004叫EEC1里面打包了发动机转速、扭矩百分比等信号。J1939-71应用层文档给每个PGN定义了固定的数据布局因此只要知道PGN就能从数据字节中反推出发动机各项参数。从PGN到CAN ID有一个很经典的计算关系。29位ID的布局是优先级占3位扩展数据页占1位数据页占1位PDU格式PF占8位PDU特定PS占8位源地址占8位。对于EEC1这种广播型PGN优先级通常是6PF0xF0PS0x04源地址SA可以设为0x00模拟发动机ECU。于是CAN ID 0x18F00400这个ID是J1939里非常常见的一个扩展帧ID经常在总线日志里出现。注意它是29位扩展帧在PCAN-View里发送时必须勾选Ext帧类型否则ID会被截断成标准11位总线上的网关根本不会认。报文数据域里则是由一个个SPN可疑参数编号组成的信号。SPN可以理解成“一个独立物理量的编号”例如SPN 190就是发动机转速SPN 84是车速SPN 245是总车辆行驶里程。J1939的数据每个PGN最多8字节每字节可能包含多个SPN也可能一个SPN跨多个字节这在解析时很容易出错。2.3 1500rpm到底对应什么数据在EEC1PGN 61444中发动机转速对应的SPN是190占2个字节起始位位于字节1从0开始编号就是Byte0。它的分辨率是0.125 rpm/bit偏移量为0。换算公式很简单原始值 物理值 / 分辨率 1500 / 0.125 1200012000换算成十六进制是0x2EE0。但CAN总线上的多字节整数遵循小端字节序低字节在前所以需要把低字节E0放在前面高字节2E放在后面即数据域前两个字节是 E0 2E。那么一个完整的EEC1报文如果只关心转速数据域可以写成8个字节E0 2E 00 00 00 00 00 00其中Byte0~Byte1SPN 190 发动机转速原始值0x2EE01500rpmByte2SPN 512 驾驶员需求发动机扭矩百分比简化填0Byte3SPN 513 实际发动机扭矩百分比简化填0Byte4以后发动机扭矩模式等相关信号简化填0。这里要提醒一点如果你后续要从真车上录Trace来对照会发现发动机ECU发出来的EEC1报文Byte2、Byte3通常不是0而是实时扭矩参数。但作为功能测试只要网关关注的是SPN 190其它字节填0不影响转速的解析。反过来如果你把转速字节的低位和高位顺序搞反了比如填成2E E0网关读出来的物理值就是12000 * 0.125 1500? 不对0x2EE0和0xE02E是不同的0xE02E 57390乘以0.125约7173rpm明显异常。所以小端序这件事必须刻在脑子里。3. PCAN-View实操10分钟跑出1500rpm3.1 先确认驱动和通道在开始发报文之前先把PCAN的驱动装好。PCAN-USB插入电脑后设备管理器里会识别出一个叫“PCAN-USB”的接口可能需要安装PCAN官方驱动包。装完后PCAN-View会自动把可用的通道列出来。打开PCAN-View在启动界面的“选择通道”里选PCAN-USB。如果这里下拉框是空的优先检查驱动是否安装成功以及USB线是不是接触不良。还有一个小坑是如果电脑里同时装了PCAN-View和其他CAN工具工具之间可能会抢通道导致PCAN-View提示“内部错误”或者“通道被占用”。解决办法是关掉其它软件或者重启一次PCAN-View。这里我建议顺手把PCAN-View里的“Trace”功能打开保存一份总线日志。尤其是刚开始联调的时候后续排查网关为什么没有收到数据Transcript Log能帮大忙。3.2 用250kbps建立一个J1939总线J1939的默认波特率是250kbps这一点跟乘用车常用的500kbps有区别。如果你直接拿着别人配置好的PCAN-View工程有可能默认还是500k连上去之后整条总线上全是错误帧怎么看怎么不对劲。在PCAN-View里面设置波特率的位置非常显眼选择250kbit/s然后点击确认。此时PCAN-View会显示总线状态为“Bus Active”。如果你是先在PCAN-View里开启通道再接VG710的电源总线状态从Active变为了BusOff或者一直报错那就要去看CAN_H和CAN_L是不是接反了或者终端电阻没接好。一个总线的“心跳”现象是很有用的自检方法只有PCAN-USB连接在总线上的时候另一端悬空或者只接了电阻PCAN-View里不会显示其他报文总线是安静的。这时网关一旦上电并开始正常工作总线上会立刻出现网关自己的周期性报文你可以马上确认网关CAN收发器是否活着。所以我的建议是先开PCAN-View并激活总线再给网关供电这样你能清楚地区分哪些报文是网关发的哪些是PCAN要发的。3.3 发送EEC1报文并验证VG710总线状态正常后进入PCAN-View的Transmit窗口新建一条发送报文ID十六进制18F00400帧类型Extended扩展帧数据长度DLC8数据十六进制E0 2E 00 00 00 00 00 00在PCAN-View里Transmit窗口可以设置多行报文每一行可以配置为单次发送或者周期发送。第一次验证时我习惯先选择“Manual”手动发送一次点击Send按钮后这条报文就会立刻出现在Receive窗口里。此时能在总线上看到自己发出的报文说明链路基本通了。但“链路上有报文”和“VG710解析出1500rpm”是两回事。要验证网关有没有正确解析通常有几个途径。如果网关有串口调试日志直接看日志里是否打印出“EngineSpeed1500”如果网关接入的是云平台远程观察到车辆数据里有转速字段变化如果现场有CANoe或者PCAN-View本身连接在同一总线上可以同时监听网关是否发出包含车速、转速的上行CAN报文比如通过诊断协议读取。我当天实际遇到的情况是VG710通过串口连接的调试助手打印出了一条JSON日志里面带EngineSpeed字段值正好是1500.0rpm。那一刻基本确认了PCAN模拟的报文已经成功让网关“相信”发动机在运转。整个过程不加准备时间就是输入一条报文点击一次Send不超过3分钟。3.4 让报文按周期循环发送真实发动机ECU不可能一帧EEC1报文就完事它会以固定周期持续发送。J1939里EEC1的推荐发送周期通常非常短常见是10ms或20ms。在PCAN-View中把Transmit窗口的那一行改成“Periodic”周期发送并把周期填成20ms然后点击开始发送。此时PCAN-View左下角的发送计数会不停跳动总线负载率也会相应上升。为什么周期不能随便填如果周期太长比如1秒一帧很多网关程序里会有“信号超时”判断可能会把转速标志位设为无效导致你看到的转速数据偶尔变0。如果周期太短比如1ms一帧250kbps总线上纯EEC1的负载率会非常高甚至影响其它报文的发送。我一般先20ms起步如果网关需要更快的响应再逐步减小到10ms。当周期发送跑起来后VG710日志里的转速会稳定维持在1500rpm上下不再跳动。到这一步PCAN-View手动模拟已经完成了90%剩余的时间我们可能会去验证转速变化、故障码注入等更多场景这时候就该考虑脚本化。4. 用Python脚本把无车测试自动化4.1 为什么需要脚本化模拟PCAN-View适合快速验证单个工况但实际网关联调远不止“发一条报文看到1500rpm”这么简单。比如你要验证上电后转速从0逐步爬升到1500rpm再回落到怠速的场景或者要模拟发动机在某一时刻发送故障码靠手点Send按钮完全不可行数据变化太快人也容易点错。脚本化最大的优势是可控性和可重复性。把一组发送规则写成代码测试环境重构后几分钟就能恢复现场回归测试也能一键跑完。而且脚本一旦接上CI系统甚至可以做到每天晚上自动跑一遍无车台架的功能验证第二天上班直接看日志和报告。J1939模拟脚本在技术栈上其实很简单就是通过PCAN官方的PCAN-Basic API或者python-can库周期性地把CAN报文塞给PCAN-USB适配器。如果你用的是python-can库还可以无缝切换到别的CAN接口硬件代码兼容性更好。4.2 最小可用的周期发送脚本下面给一套我实际在用的最小Python脚本骨架。它依赖于python-can库需要通过pip install python-can安装同时电脑上必须已经装好PCAN驱动并且PCAN-USB已经识别为通道。import time import can # 初始化PCAN通道波特率250kbps bus can.interface.Bus( channelPCAN_USBBUS1, interfacepcan, bitrate250000 ) # J1939 EEC1报文源地址0x00 # ID: 0x18F004008字节数据1500rpm msg can.Message( arbitration_id0x18F00400, is_extended_idTrue, data[0xE0, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], is_fdFalse ) period 0.02 # 20ms周期 try: while True: bus.send(msg) time.sleep(period) except KeyboardInterrupt: print(stop) finally: bus.shutdown()这个脚本启动后会以20ms周期持续发送EEC1报文。在PCAN-View的Receive窗口里你能看到同一帧ID每20ms出现一次与手动周期发送效果一致。在此基础上把转速做一个渐变会更有用。比如从怠速800rpm爬到1500rpm再回到800rpmdef rpm_to_raw(rpm): return int(rpm / 0.125) rpm 800 step 10 while True: raw rpm_to_raw(rpm) data[0] raw 0xFF data[1] (raw 8) 0xFF bus.send(can.Message( arbitration_id0x18F00400, is_extended_idTrue, datadata, is_fdFalse )) rpm step if rpm 1500: step -10 if rpm 800: step 10 time.sleep(0.05)这里就涉及到了计算字节序的代码实现用raw 0xFF取低字节用raw 8取高字节完全对应前面提到的E0 2E规则。实际操作中我会把这个渐变过程打印到日志里方便跟网关上报的转速做对比。4.3 模拟真实工况的扩展玩法脚本模拟不限于EEC1转速还可以做很多扩展。比如额外模拟一个车速信号。车辆速度SPN 84在J1939的CCVS参数组里不同主机厂对CCVS的PGN实现略有差异建议先去查J1939-71确认目标车型的PGN和字节位置然后在脚本中通过另一个CAN ID周期发送。因为网关往往不会只依赖转速判断车辆状态车速也是重要的“车辆在行驶”的证据。另一个常见需求是总里程的模拟。很多车载网关会上报“obd总里程”这个值来自仪表或发动机ECU。总里程SPN 245一般位于CCVS或仪表相关PGN中具体解析方式取决于网关策略。如果现场有真车数据最好先用PCAN-View在实车上录一段Trace把总里程对应的PGN和数据抓出来再拿到台架上复现。这比对着文档猜要可靠得多。故障码注入也可以做。J1939的DM1报文PGN 65226CAN ID 0x18FECA00用于发送激活故障码。脚本里周期发送DM1报文数据里带上你指定的SPN和故障模式标识符网关就能在诊断日志里看到故障。这套无车台架玩法非常适合验证远程诊断和故障上报逻辑。5. 无车台架测试的踩坑记录5.1 常见问题速查表实际操作中我踩过的和见过同事踩的坑整理成下面这个表遇到类似现象可以直接对着排查。现象可能原因解决办法PCAN-View里选不到PCAN-USB通道驱动没装好或通道被其它软件占用重装PCAN驱动关闭其它CAN工具重新插拔USBCAN总线一直报错误帧波特率不对或没有终端电阻确认250kbps在总线两端检查120欧姆终端电阻网关日志里转速一直为0报文发送周期太长或网关没收到EEC1缩短发送周期到20ms检查CAN_H/CAN_L是否接反收到了报文但转速数值异常大多字节数据字节序填反了确认小端序1500rpm填E0 2E而不是2E E0网关完全没有响应KL15点火信号没置高或供电异常用万用表量KL15电压确认网关已退出休眠PCAN-View里能看到发送计数在涨但网关串口无数据网关应用层过滤了该PGN用Trace日志对比正常EEC1 ID检查源地址是否被网关策略拒绝总线偶发BusOff线缆过长、接触不良或两个设备不共地检查GND共地压接端子是否牢固缩短CAN线长度5.2 容易被忽视的细节和我的习惯有几个细节我是在几次排错之后才总结出来的分享出来帮大家少走弯路。CAN_H和CAN_L接反了是最隐蔽的问题。因为CAN总线是差分信号接反后仍然有波形但电平完全反相PCAN-View里会看到大量错误帧却不会完全没反应。很多新手这时候去怀疑波特率、怀疑终端电阻最后发现只是两根线对调一下的事。所以接线完我一般先用万用表量一下OBD母座6脚和14脚到PCAN插头的连通性确认不是交叉的。第二个细节是共地问题。PCAN-USB这个适配器通过USB从电脑取电本身的地与电脑电源地连在一起。而VG710如果用的是另一台稳压电源供电那网关电源的地和PCAN地必须要连起来。否则CAN收发器参考地不一致信号会漂移严重时直接把收发器打坏。我在台架上习惯用一根粗黑线把电源地、OBD母座地、PCAN地全部接在同一个接线端子上。还有一个容易被忽略的地方是PCAN-View里的Trace文件路径。如果电脑换了用户账号登录PCAN-View可能会因为权限问题保存不了Trace导致你点录制备份却什么都没留下。建议先把日志路径配置到D盘或者当前用户有写权限的目录再开始录Trace。我在测VG710的时候每次都会同时开Trace和一个串口日志窗口两边对时间一旦网关行为异常能快速定位是CAN输入不对还是网关内部解析有问题。最后再分享一个我的工作习惯上电前先不急着发报文先让PCAN-View在总线上挂一小会儿看看VG710自己是否会主动发出报文。很多网关会周期广播自己的状态或者周期发送诊断请求这能帮你判断网关的CAN通道和供电是否正常。一旦确认网关在总线上“活跃”再开始用PCAN发送EEC1报文事半功倍。如果直接把所有报文一股脑发上去出了问题反而不知道是网关没醒还是报文没被认。测试这行稳一点永远比快一点省时间。
返回列表