ARTICLE DETAIL

资讯详情

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

基于CANoe搭建GB/T 27930-2023充电通信仿真测试环境实战

基于CANoe搭建GB/T 27930-2023充电通信仿真测试环境实战 GB/T 27930-2023实施之后很多做充电测试的朋友开始重新审视自己的测试台架。以前跑顺的2015版脚本在2023版的时序和报文定义上会出现各种水土不服。我这次就用CANoe搭了一个既能模拟BMS、又能模拟充电机的双向交互测试环境整个过程整理成一篇完整实战记录。这篇文章适合刚接手充电通信测试的工程师也适合想用CANoe做协议仿真的老手快速落地一个方案。只要照着下面的步骤走不需要额外买昂贵的台架设备普通PC加一个CAN接口卡就能跑通完整的充电交互流程。1. 项目概述这次要搭什么解决的问题是什么1.1 GB/T 27930-2023带来了哪些变化GB/T 27930是电动汽车传导充电用通信协议的国家标准定义了直流充电桩与车辆BMS之间通过CAN总线交互的报文格式、时序要求与故障处理机制。2023版相比2015版在报文命名、参数集合、握手流程、故障分类和充电控制逻辑上都有调整。尤其是对充电启动前安全握手、绝缘检测状态确认、动力电池充电需求参数上报等环节的约束更严格了。这些变化对测试工作最直接的影响就是用老版本数据库去解析新协议的报文会出现信号对不上、周期判定错误、状态机跳转不满足条件等问题。手上没有一套按2023版搭起来的仿真环境很多测试脚本和台架验证根本没法推进。所以搭建一个可配置、可重复、可注入故障的协议测试环境是开展后续所有验证工作的前提。1.2 这次测试环境的目标和范围本项目不涉及真实电池包和真实充电桩而是用CANoe的仿真功能在一台PC上同时模拟BMS节点和充电机节点让两个节点按照GB/T 27930-2023的通信流程自动交互。项目目标拆开大致有这么几块能手动或自动触发充电握手两个节点正常完成从握手、辨识、参数配置到充电状态上报的完整流程。能对关键报文进行实时解析在Trace窗口看清楚周期、ID、信号值、CRC校验结果。能通过面板控件控制仿真流程比如手动发送某帧报文、改变某个信号值、暂停某个节点。能注入常见故障比如丢帧、超时、CRC错误、错误帧验证对端节点的容错逻辑。能记录测试日志方便回归对比和问题追溯。简单来说这套环境的价值在于把原本需要真车、真桩才能做的事情搬到桌面上来用软件仿真先把协议逻辑跑通再去台架上做硬件级验证能省下大量排错时间。1.3 为什么选CANoe做载体做CAN通讯测试业界用得最多的就是Vector家的CANoe。它本身的定位是总线开发与测试的全流程工具既能监控总线也能做仿真节点。DBC数据库管理、CAPL脚本编程、可视化面板、日志记录这些模块都是现成的不需要自己去拼凑工具链。用CANoe搭BMS与充电机通信测试环境有几个天然优势原生支持DBC文件可以结构化定义报文和信号仿真节点直接按数据库自动收发报文不用手动组装每一帧。CAPL语言基于C语法学习成本低状态机、定时器、报文回调写起来都很顺手。面板功能可以在屏幕上做一个虚拟充电操作界面不能连真实硬件的时候也能完整演示。故障注入和总线统计功能完善能对DLC错误、Checksum错误、总线负载率等做量化分析。不过说句实在话CANoe的学习曲线不低尤其是第一次用的人装完软件打开工程面对一大堆窗口会有点懵。这篇文章就把最关键的操作路径理清楚省得在无关功能里绕路。2. 测试环境整体设计架构、流程与工具链2.1 整体仿真架构设计在设计这套测试环境时我采用两个仿真节点加一个监控节点的架构。两个仿真节点分别承担BMS角色和充电机角色监控节点不参与报文交互只挂在总线上抓包分析。BMS节点负责的角色包括发起握手、解析充电机参数配置报文、上报电池充电需求、上报充电状态、接收充电机中止充电报文。充电机节点负责的角色包括响应握手、下发充电机辨识信息、下发时间同步信息、下发充电参数配置、实时接收BMS需求并模拟输出调整、在异常情况下发起中止充电。这两个节点在同一个CANoe工程里相互通信好处是全部报文都在内部总线上可见任何一个交互环节出问题都能在Trace里立刻定位到是哪一方没按标准执行。如果后续需要接入真实充电机或者真实BMS只需要把对应仿真节点摘掉换成真实设备接入总线即可架构不需要大改。这套架构还有一个灵活点状态机逻辑独立于报文定义。DBC里只定义报文字段状态机放在CAPL脚本里这样协议版本升级或者被测件行为变化时只需要调整脚本不需要动数据库维护成本很低。2.2 DBC数据库的设计思路DBC文件是CANoe工程的数据基石。在GB/T 27930-2023的测试环境里DBC里需要定义的内容包括总线上的网络节点充电机节点、BMS节点。所有涉及的报文握手报文、辨识报文、参数配置报文、充电需求报文、充电状态报文和中止充电报文。每个报文里的信号握手阶段标识、电池类型、充电需求电压电流、SOC、剩余充电时间等。报文的周期属性这个在后期写CAPL定时器时会用到。我第一次搭这个环境时没有好好设计DBC里的节点名和报文名后面写CAPL脚本时经常要回头查数据库效率很低。建议在动手前先对照标准把报文清单列出来把每个报文的中文含义、英文缩写、收发方向、周期都确认好再建DBC。别嫌这一步麻烦前期多花半小时后面能省半天。2.3 软件与硬件环境清单搭建这套环境不需要专门的测试台架硬件要求其实很低。以下是我实际使用的一套配置运行Windows的PC一台建议内存16GB以上CANoe对内存比较敏感工程文件大了以后太卡会影响操作。CANoe软件版本12.0以上都可以版本越新对2023版协议的一些信号解析和面板功能支持越好。CAN接口硬件比如Vector的VN1610或VN1640笔记本用户建议用USB接口的型号方便移动。一条CAN转DB9线缆按实际接口需求准备如果接口卡自带线缆可以跳过。如果需要和真实BMS或充电机联调还需要按实际设备的接口定义准备线束和终端电阻。注意CANoe软件需要从正规渠道获取授权不要使用来路不明的破解版本。调试协议过程中如果出现奇怪的时序错乱问题很大一部分是破解版功能裁剪导致的。2.4 工具链与版本选择说明在实际项目中我建议在CANoe之外搭配CANdb、CAPL Browser和ILogger这几个模块使用。CANdb用来编辑DBCCAPL Browser用来写仿真逻辑ILogger用来记录和回放总线数据。有一点要提醒如果公司有多台电脑协同开发最好统一CANoe版本避免低版本工程在高版本软件里打开后出现数据库路径失效、节点配置丢失的情况。我在一个项目里就遇到过同事用15.0保存的工程被我用13.0打开后CAPL脚本里的部分关键字不兼容编译报错一堆。后来统一到同一个大版本才解决问题。3. 手把手搭建CANoe测试环境3.1 新建工程与CAN通道配置打开CANoe后第一步是新建一个工程。建议选择“Real Bus CAN”类型的工程模板不要选纯离线分析模板因为我们需要实际跑仿真交互。工程命名建议用“GB_T_27930_2023_BMS_Charger_Test”这样的格式方便后续归档。工程创建完成后进入Configuration窗口需要确认总线通道设置。在Simulation Setup里把两个仿真节点挂到同一个CAN通道下。因为本次是纯仿真环境不需要指定硬件通道但需要注意选择正确的总线类型和波特率。GB/T 27930协议规定的CAN通信波特率一般为250 kbit/s这个参数在总线属性里必须提前设置好。如果波特率不匹配两个仿真节点之间会出现大量错误帧Trace里看起来像是协议解析失败实际是物理层就没对上。3.2 使用CANdb定义数据库文件在CANoe工程里DBC文件可以通过Tools菜单下的CANdb来创建。也可以直接在工程里新建一个数据库。以下是一个简化示例演示BMS握手报文在DBC里的定义方式VERSION NS_ : NS_DESC_ CM_ BA_DEF_ BA_DEF_DEF_ ... BS_: BU_: BMS_ECU Charger_ECU BO_ 1280 BMS_HandshakeMsg: 8 BMS_ECU SG_ HandshakeFlag : 0|81 (1,0) [0|255] BMS_ECU SG_ ProtocolVersion : 8|81 (1,0) [0|255] BMS_ECU SG_ BatteryType : 16|81 (1,0) [0|255] BMS_ECU这个例子里1280是十进制报文ID对应十六进制0x0500。这是我为了演示方便自定义的ID实际标准中的报文ID定义要以GB/T 27930-2023标准文本为准。你在建DBC时一定先查标准中每个报文的ID、周期和数据字节定义然后在CANdb里逐一录入。信号定义时要注意两个容易出错的地方一个是字节序标准里多数信号用Intel格式也就是小端字节序选错了解析出来的值会完全不对另一个是信号起始位起始位计算基础是0位不是1位。这两个细节错一个后面Trace里的信号值就全是乱的。3.3 配置仿真节点并关联DBCDBC建好之后回到CANoe的Simulation Setup。在窗口左侧的网络节点列表里添加两个网络节点分别命名为BMS_ECU和Charger_ECU。然后把DBC文件关联到总线上并在每个节点属性里指定该节点使用的CAPL脚本文件和DBC数据库。这里有一个关键操作要让节点真正参与仿真节点属性里的Simulation Mode必须设置为“Simulate”并且在节点Assignment里把DBC里定义好的发送报文分配给对应节点。如果这一步漏了即使DBC和CAPL脚本都正确节点也不会自动发送任何报文。3.4 编写CAPL脚本状态机控制核心交互CAPL脚本是这套环境的核心驱动。我先写一个简单的框架展示状态机的基本结构variables { msTimer tSendHandshake; int state 0; } on start { setTimer(tSendHandshake, 100); } on timer tSendHandshake { switch (state) { case 0: // 发送BMS握手报文 BMS_HandshakeMsg.HandshakeFlag 0x01; output(BMS_HandshakeMsg); setTimer(tSendHandshake, 500); state 1; break; case 1: // 等待充电机响应并发送下一帧 break; default: cancelTimer(tSendHandshake); break; } } on message Charger_ECU.* { // 根据对端报文切换状态 }这段代码的逻辑是BMS节点启动后先发送一帧握手报文然后进入等待对端响应的状态等收到充电机节点返回的报文后再决定下一步动作。实际项目里状态会更多比如握手超时、辨识超时、参数配置确认、正常充电循环、人为中断等。写CAPL脚本时有几个经验可以分享定时器的周期不要设置得太短一般握手阶段按100毫秒到500毫秒的节奏来真实协议里握手和辨识也没有那么快的刷新频率。报文发送函数output和显式发送的区别要注意。直接对DBC里的报文变量赋值再output是最简单也最不容易错的方式省得自己手动组数据字节。所有状态跳转都要加超时保护。即使是最简单的demo程序也建议加一个看门狗定时器否则状态机卡死时排查起来很费劲。3.5 设计控制面板在CANoe里新建一个Panel把常用操作做成按扭和显示控件。我习惯在面板上放的控件包括充电启动按钮点击后BMS节点发送握手报文。充电停止按钮触发充电机节点发送中止充电报文。故障注入开关可以切换是否在下一帧报文中制造CRC错误。状态显示框显示当前状态机的运行状态。面板控件关联到CAPL变量或者DBC信号上。比如按钮被点击时触发一个系统变量的事件CAPL脚本里通过on sysvar事件响应按钮操作。显示框则直接关联DBC信号值这样充电需求电压、电流、SOC等数据就能实时看到。提示面板控件位置摆放建议参考真车仪表台逻辑启动和停止按钮分开角落放避免误触。测试时经常遇到误按停止按钮导致流程中断重跑一遍很浪费时间。3.6 运行工程并验证基础通信完成以上配置后就可以点击运行了。正常情况下应该在Trace窗口里看到周期性报文在总线上流转。先观察第一帧握手报文再观察充电机节点是否作出响应。如果Trace窗口是空的优先检查两个地方节点是否处于仿真状态DBC是否成功加载。如果Trace窗口有报文但全是错误帧检查波特率和终端电阻。4. 核心环节实现协议状态机与测试用例设计4.1 充电握手阶段的仿真实现GB/T 27930-2023的充电流程最先进入的是握手阶段。BMS确认物理连接有效后会发送握手报文充电机收到后回复握手确认报文。双方握手成功后才允许进入辨识阶段。在CANoe里模拟这个阶段关键是状态机的三个出口正常握手、握手超时、握手失败。正常握手就是标准的收发流程握手超时时BMS在固定时间窗口内没收到充电机响应此时协议要求重新发起握手或上报异常握手失败是收到了对端报文但报文内容里的版本号或握手标志不匹配。我在CAPL里实现时给握手阶段设置了一个3秒的看门狗定时器超过时间没触发下一次状态跳转就自动进入告警状态。这样既能在测试时卡住问题也不会让脚本一直死等。4.2 辨识与参数配置流程握手成功之后通信流程进入辨识阶段。BMS发送辨识报文充电机回复辨识结果报文随后双方进入充电参数配置阶段。在这个阶段充电机会下发时间同步信息和充电机最大输出能力BMS会根据电池当前状态上报充电需求。在CANoe里做这部分仿真时我建议把充电需求参数做成动态变化的信号。比如模拟一个SOC从20%逐渐上升的过程充电需求电流随着SOC的变化而变化。这样看起来更接近真实场景也能验证对端节点对参数变化的响应逻辑。动态信号不需要很复杂的逻辑CAPL里用定时器每隔1秒更新一次DBC信号值然后output发送即可。4.3 CRC校验与报文解析车辆和充电桩之间的通信报文很多都包含CRC校验字段。2023版协议对校验字段的覆盖范围和算法有一定调整。在CANoe里做CRC校验测试一般有两种做法正常情况发送节点按照协议计算出正确的CRC值附在报文中接收节点解析时校验。这个逻辑可以写在CAPL里相当于在仿真节点内部实现一次完整的编码解码。异常情况发送节点故意使用错误CRC验证接收节点能否识别并做出错误处理。判断CRC是否正确除了Trace里可以配置显示校验状态之外还可以用CANoe的CAPL函数对收到的报文逐字节重新计算CRC然后与报文里的CRC字段比对。这样做有一个好处就算Trace窗口的解析显示不直观脚本也能自动判定并记录结果。4.4 故障注入与异常测试CANoe做协议测试的最大价值就是能非常方便地注入故障。我在这个测试环境里重点做了下面几类异常测试丢帧测试在CAPL里加一个计数器每隔N帧就丢弃一帧不发送观察对端节点是否能容忍丢帧或触发超时重发。报文周期异常把定时器周期从标准值改快或改慢检查对端节点的通讯超时判断是否生效。CRC错误注入保留报文数据字节不变只翻转校验字节看接收节点的错误帧处理逻辑。总线错误模拟人为发送错误帧或者让某个节点短暂退出总线观察另一个节点的总线恢复机制。注意故障注入开关一定不要放在默认开启状态。我有一次做完测试忘记关闭CRC错误注入开关结果第二天跑回归自动化脚本挂了两个小时才排查到原因就是因为报文里一直在带错误CRC。4.5 实时监控与日志记录运行测试时我习惯把Trace窗口、Graphics窗口和Logging窗口同时打开。Trace窗口负责看单报文的收发细节Graphics窗口看电压电流等模拟量的变化趋势Logging窗口负责把全程总线数据记录下来。记录日志时需要注意文件大小尤其是长时间回归测试总线数据量非常大。建议按测试用例分组每个用例单独生成一个日志文件不要所有用例塞到一个文件里不然后面用CAPL回放文件时会非常难定位。5. 常见问题与排查技巧实录5.1 建工程和DBC加载的坑刚开始接触CANoe的人最容易遇到的一类问题就是DBC加载不上。表现为Trace窗口里看到的都是纯粹的十六进制数据帧没有报文名和信号名。这个问题的原因通常是DBC文件路径失效或者工程文件从别的电脑拷过来时数据库文件没有一同拷贝到工程目录下。解决办法是打开Simulation Setup里的Database配置查看DBC文件路径是否有效。如果路径变红就把DBC文件拷贝到当前工程目录下重新添加引用。还有一个常见问题Trace窗口的ID和Name两列是空白的。这个和显示配置有关在Trace窗口里右键打开窗口布局设置确认ID、Name这些列是否被勾选显示。如果列已经勾选但还是空白多半是DBC没关联到总线或者节点没有分配到对应报文。5.2 仿真节点不发送报文节点在仿真模式下不发送报文这个问题我排查过很多次。最常见的原因有三个节点没有关联到正确的DBC导致系统不知道该节点有哪些报文。节点属性里的Simulation Mode没有设置为“Simulate”还在“Passive”模式下。CAPL脚本没有关联到节点或者脚本编译失败。编译失败的提示需要留意很多时候是变量名写成了DBC里不存在的信号名。排查这类问题时我建议先看Trace窗口有没有周期性错误帧如果有说明通信链路是通的问题出在节点配置如果完全没有帧优先检查节点是否激活。5.3 报文周期不稳地影响协议流程CANoe的仿真定时器虽然基于系统时间但当工程里挂载大量日志记录和分析功能时定时器周期可能出现轻微抖动。在协议时序要求严格的测试中这种抖动会影响超时判定。解决思路是使用高优先级定时器或者在脚本里做时间戳补偿。具体做法是在on timer回调函数里读取当前时间与上一次发送时间做差如果偏差过大动态调整下一次的定时器周期。5.4 硬件连接问题导致通信中断在做真实设备联调时经常会遇到CAN报文时有时无的情况。此时优先检查CAN_H和CAN_L是否正确连接有没有接反。终端电阻是否启用。CAN总线两端需要120欧姆终端电阻只在一端有电阻时信号反射会导致波形畸变。波特率是否一致包括CANoe软件里设置的波特率和真实设备的波特率。5.5 常见问题速查表现象可能原因解决办法Trace窗口无报文节点未激活或DBC未加载检查Simulation Setup节点状态和数据库路径Trace窗口报文没有ID列和Name列显示列未配置右键窗口配置列显示报文持续错误帧波特率不匹配统一设置为250 kbit/s节点不发送报文节点被配置为Passive修改为Simulate模式CRC校验失败校验算法不一致对照标准重新实现CRC逻辑定时器周期不稳系统负载过高关掉不需要的分析窗口使用高优先级定时器收到报文但信号值异常字节序或起始位定义错误核对DBC信号定义与标准数据格式状态机卡死缺少超时看门狗添加全局超时定时器强制状态跳转6. 基于这个环境还能扩展什么这套CANoe测试环境搭建好之后后续扩展空间很大。最常见的一个扩展方向是接入诊断功能因为很多BMS和充电机在充电启动前还需要进行安全访问认证也就是SeedKey。CANoe提供了一套关于AES-128算法的SeedKey DLL接口可以把算法编译成DLL文件供CAPL调用从而模拟完整的诊断解锁流程。这个扩展能在充电流程测试中多覆盖一层安全逻辑验证。另一个方向是用Python驱动CANoe做自动化测试。CANoe提供了COM接口Python脚本可以通过win32com库调用CANoe的API实现在外部控制工程运行、发送报文、读取Trace数据、生成测试报告。我做过一个小规模回归脚本用Python把SOP计算、通信超时、故障注入这些用例串起来跑效率比手动操作高了很多。另外一个值得做的事情是把DBC和CAPL脚本跟版本管理工具结合起来。GB/T 27930-2023协议后续如果有修订或者企业自定义扩展改动会涉及DBC信号、CAPL状态机、测试用例三个层面。没有版本管理的测试脚本很容易在频繁改动中丢失正确的基线版本。最后分享一个我在实际项目里积累的经验无论协议版本怎么变打牢CAN总线的基础调试功底永远不吃亏。做GB/T 27930-2023协议测试核心不是背报文ID而是理解充电交互的状态流转逻辑。先把这个最小仿真环境跑通再去探索更复杂的诊断、自动化、HiL台架路径会顺很多。工具只是手段把协议逻辑搞清楚测试环境才能真正为自己所用。
返回列表