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

资讯详情

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

CANoe与CAPL在HiL测试中的核心作用与实战指南

CANoe与CAPL在HiL测试中的核心作用与实战指南 1. 招聘要求背后的真实诉求HiL测试到底在测什么这两年只要打开汽车测试相关的招聘软件输入HiL测试十个岗位里有八个要求写熟练掌握CANoe能独立编写CAPL脚本。很多刚入行或者准备转行的人会疑惑CANoe不就是个报文监控工具吗CAPL不就是个脚本语言吗为什么这两项技能在汽车测试岗位里被捧得这么高先回答最核心的问题HiL测试Hardware-in-the-Loop硬件在环到底在做什么。简单说HiL测试是把真实的ECU电子控制单元接在一个实时仿真系统上用仿真模型替代真实车辆环境让ECU以为自己装在一辆真车里然后对它进行各种场景测试。举个例子你在实验室里测试一个ESP车身稳定控制器。你把真实的ESP控制器接上HiL台架台架里跑着整车的动力学模型——发动机扭矩、轮胎抓地力、车身姿态、路面附着系数都是软件仿真出来的。你通过操纵仿真模型让车辆进入侧滑状态ESP控制器通过传感器采集信号计算出需要给哪个轮子施加多少制动力然后输出PWM信号去驱动液压单元。整个过程发生在毫秒级ECU感受到的电压、电流、通信信号和真车上一模一样。这正是HiL测试的核心价值——在研发早期不需要一台完整的实车就能把ECU的大部分功能、故障处理逻辑、通信协议都验证一遍。那么问题来了既然HiL台架跑的是仿真模型ECU工作靠的是CAN总线和外部传感器信号那总得有个工具负责两件事一是把仿真模型算出来的数据转成ECU能识别的CAN信号或模拟量信号发给ECU二是把ECU发出的CAN信号、PWM信号采集回来反馈给仿真模型。CANoe在HiL系统里扮演的角色恰恰就是这座桥梁。再往深一层说HiL测试的用例执行不是纯手动的。一个ESP控制器可能有几百条测试用例你不可能每条用例都拿着鼠标在界面上点来点去。此时就需要有一个自动化执行测试、自动判断结果、自动生成报告的机制。CAPL脚本就是干这个的。所以招聘要求写CANoe CAPL本质上不是在要求你会用某个软件、会写某种语法而是在要求你具备一项完整的职业能力理解汽车总线通信机制懂得如何用CANoe构建一个真实的通信环境同时具备编程思维能够把测试逻辑用CAPL这个专用语言落地成自动化脚本。这三层能力打包在一起就是一个HiL测试工程师日常工作的全部核心。2. CANoe在HiL测试中的角色远不止看报文这么简单很多新手对CANoe的第一印象是打开软件连上硬件能看到总线上的报文在滚动解析出ID、数据、周期。这个认知没有错但对于HiL测试来说CANoe能做的事远超于此。我按实际工作的维度来拆解。2.1 总线仿真让ECU以为自己在车上没有CANoeHiL台架上真实ECU的CAN总线几乎是静默的。因为仿真模型跑在实时机里实时机计算出的车速、转速、挡位等信号必须以CAN报文的形式周期性发送给ECU。ECU接收不到这些信号或者信号周期不对它会直接进入故障模式甚至整车功能全部停机。CANoe在这里的核心能力是剩余总线仿真Restbus Simulation。什么意思呢一台整车上可能有十几个ECU它们之间互相发报文、互相响应。HiL测试只把被测ECU放在台架上其他ECU都是不存在的。但真实ECU哪知道其他ECU不在它按协议要求等着接收其他ECU发来的报文。此时就用CANoe来模拟所有不存在的ECU按照DBC数据库定义的报文周期、信号取值、信号变化规律把整车环境的数据周期性发到总线上。被测ECU收到这些数据才会认为自己处于一个正常的整车环境中才会正常地执行控制逻辑。这里有一个很关键的细节剩余总线仿真不只是定时发一帧报文而已。你得模拟信号之间的耦合关系。比如你模拟发动机ECU发送转速信号、扭矩信号这两个信号不是独立变化的——加速踏板踩下去转速上升扭矩上升。如果你只是把转速拉高扭矩还停留在怠速值ECU内部一些判断逻辑就会被误导测试结果就废了。所以在做剩余总线仿真时你需要搭一套信号间的关系模型这恰恰也是CANoe强大的地方它支持在CAPL里写逻辑来改变信号也支持通过信号发生器Generator定义信号间的联动关系。2.2 信号级控制从物理量到总线信号的无缝转换在HiL系统中实时机比如dSPACE、NI PXI负责跑车辆动力学模型。这些模型算出来的是一些物理量比如车速是5.2 m/s发动机扭矩是120 Nm。但这些数据在CAN总线上跑的时候对应的是某个报文里的某个信号而且信号的定义是经过DBC文件的缩放和偏移处理的——原始值是0~10000量程是-50到200分辨率0.025。CANoe与实时机之间的配合正是HiL系统架构里最值得花心思的部分。通常实时机通过专用的IO接口或以太网协议把物理量传给CANoe的仿真通道CANoe收到后根据DBC定义把物理量换算成总线上的原始值打包成CAN帧发送到被测ECU的CAN通道。ECU输出信号则走反向流程CANoe从总线上读回ECU发出的报文解析成物理量再实时机模型做闭环反馈。这里面很容易踩的坑是CANoe和实时机之间同步时序不匹配。HiL测试要求仿真步长和总线报文周期严格匹配。比如模型以1ms步长在跑某个CAN报文是10ms周期发送一次中间丢了9个模型计算结果这很正常因为报文本身就做不到每毫秒发一帧。但如果某个信号是模型里的关键状态量恰好在发送的瞬间被更新了就会出现信号抖动甚至跳变。实际项目里我们会在实时机和CANoe之间做信号缓存和采样保持的策略避免信号毛刺影响到ECU的控制逻辑。2.3 诊断、XCP、标定HiL测试里绕不开的三板斧现代ECU不只有CAN通信还有UDS诊断协议ISO 14229有XCP标定协议有DoIP基于以太网的诊断。HiL测试里经常要做诊断相关的验证写入DTC故障码、读取DTC、做例程控制、刷写Bootloader等。CANoe对这些协议的支持相当完整。我在做电池管理系统BMSHiL测试时经常需要在测试脚本里动态改变某条报文的某个信号数值来模拟传感器故障然后通过诊断仪功能发送一个诊断请求让BMS进入故障处理流程再读取BMS返回的诊断响应验证DTC的置位情况是否符合预期。这套流程如果说手写诊断测试用例工作量很大但CANoe的诊断模块把这些都封装成了可调用的函数配合CAPL可以组合出非常灵活的测试序列。XCP标定在HiL测试里的作用容易被忽略但实际项目里价值极高。ECU内部标定参数如标定表、阈值、PID参数很多在台架上跑测试时有些参数是不可调整的有些参数甚至需要通过标定才能让ECU正常工作。CANoe的XCP模块可以在线读取ECU内存中的标定值也可以通过标定协议实时修改参数。我在做电机控制器HiL测试时就遇到过一个场景某个过流保护阈值在台架上整定值过高导致没办法触发保护逻辑。直接用XCP把阈值改小测试用例就跑了下去省掉了重新编译固件的几小时时间。2.4 测试管理与分析留给测试报告的底气前面说的都是发信号和收信号但HiL测试工程师还有一个同样重要的工作数据采集、分析、归档。CANoe的Trace窗口、Graphics窗口、Data窗口是测试过程中最常用的分析工具。Trace窗口能看到所有总线上报文的详细字段Graphics窗口能把信号变化画成曲线方便观察信号间的时序关系。但我想多说一句CANoe自带的记录和分析功能对于日常调试够用当测试量上来之后就远远不够了。我在做整车控制器HiL回归测试时一次测试会跑十几个小时产生的日志文件能到几十GB。这种情况下你不可能手工去翻Trace窗口。通常的做法是在CAPL测试脚本里把关键测试步骤、Expected Value、Actual Value、Pass/Fail结果全部格式化输出到日志文件后面用Python或MATLAB对日志做二次分析生成测试报告。CANoe在这一环的角色是数据源和规则执行者而真正的分析能力反而是测试工程师自己写代码的能力。3. CAPL为什么是HiL测试工程师的第二语言如果说CANoe是HiL测试的躯体那CAPL就是让躯体活动起来的神经。很多初学者第一次接触CAPL时会产生一个疑问我在学校里学的是C语言、Python为什么干这行还要学一门闻所未闻的专用脚本语言3.1 CAPL本质上是一个受限的C语言变体但它的运行模型完全围绕总线CAPL的语法和C语言高度相似有变量、函数、if/else、switch、数组、结构体、指针指针有使用限制。你完全可以把CAPL当成C语言的子集来学。但它的运行模型和普通C程序有本质区别——普通C程序是从main进入顺序执行CAPL程序是事件驱动的类似JavaScript的事件监听器模式。整个CAPL程序里没有main函数取而代之的是很多事件处理函数。比如on message 0x123当总线上收到ID为0x123的报文时自动进入这个函数执行对应逻辑on key a当你在CANoe界面上按下字母a键时触发执行on timer Timer1当定时器Timer1超时时触发执行on errorFrame当总线上出现错误帧时触发执行on start/on preStop在测量启动/停止时触发。这个模型很好理解你写的是一个长期挂在CANoe环境里的看门逻辑总线上一有风吹草动对应的事件处理函数就被激活。你在每个事件函数里写发生后应该怎么做的代码。比如写一个最简单的200ms周期发一帧报文的功能variables { msTimer tSend; // 定义一个毫秒定时器 } on start { setTimer(tSend, 200); // 启动时设定200ms定时 } on timer tSend { message 0x123 msg; // 定义一个CAN报文 msg.dlc 8; msg.byte(0) 0xAA; msg.byte(1) 0x55; output(msg); // 发送到总线上 setTimer(tSend, 200); // 重新装载定时器实现循环发送 }这段代码不长但已经把CAPL的核心模式全部体现了定时器管理、报文构造、报文发送、事件回调。你把这个逻辑再扩展加上信号值的动态修改、条件判断、状态机转移就是一套完整的ECU环境模拟逻辑。3.2 一个完整的CAPL测试用例长什么样作为HiL测试工程师你写CAPL的主要目的不是为了模拟“假的ECU”而是为了写自动化的测试用例。下面我写一个典型的BMS HiL测试用例展示CAPL如何完成构建刺激信号→采集响应→自动判据→输出报告的全流程。场景是这样的BMS有一个单体电池过压报警功能。当任意一个单体电池电压超过4.2V时BMS需要发出报警信号并在故障存储里置位一个DTC。CAPL代码如下includes { } variables { // 定义测试用的1号电池单体电压信号假设在报文BMS_CellInfo中信号Cell1_Volt // DBC里面定义好设置信号的方法这里用 $符号访问 int gTestPass 0; int gOneShot 0; diagRequest BMS_ReadDTC reqReadDtc; // 诊断请求对象 } on start { // 测量开始后先订阅需要监控的报文 setSignal(Cell1_Volt, 3.8); // 初始电压正常 write(Test case BMS_OVP_001 started); } on message BMS_Status // BMS状态报文 { // 当检测到报警信号从1变成1报警置位时记录测试结果 if (this.BMS_Alarm 1 gOneShot 0) { gOneShot 1; gTestPass 1; write(BMS over voltage alarm triggered correctly); } } testcase TC_BMS_OVP_001() { // 第一步将1号单体电压激励从3.8V逐步升高到4.5V模拟过压 int i; gOneShot 0; for (i 0; i 10; i) { setSignal(Cell1_Volt, 3.8 i * 0.07); // 每次升0.07V TestWaitForTimeout(100); // 等待100ms } // 第二步等待BMS响应 TestWaitForTimeout(500); // 第三步用诊断服务读取DTC验证故障码是否有记录 if (gTestPass 1) { // 发送诊断请求 reqReadDtc.SetParameter(0x1900); // 假设是DTC码 reqReadDtc.SendRequest(); TestWaitForDiagRequestSent(reqReadDtc, 1000); // 检查响应 if (reqReadDtc.GetLastResponseCode() 0) { TestStepPass(BMS response correct); } else { TestStepFail(DTC read failed); } } else { TestStepFail(BMS alarm not triggered); } }这个用例看起来有模有样但我必须诚实地说真实项目里CAPL代码会比这个复杂很多。原因在于第一真实项目里信号非常多不可能只测一个单体电池电压通常要同时注入多种激励——某几个单体过压、某几个单体温度过高、母线电流异常等这些信号之间还存在耦合关系。第二诊断服务并不是简单的请求-响应模型。真实诊断服务有会话控制、安全等级还有一些子功能需要先通过seed-key解锁CAPL里要写好安全算法的实现函数。第三测试结果不能只写好和坏。真实DTC有确认DTC和待处理DTC的区别报警的触发还有延迟时间的要求。比如BMS要求过压状态持续2秒以上才报警你在编写测试时要把延时判据也考虑进去。如果没有延时ECU判定为瞬时故障你的用例编写逻辑就完全错了。3.3 CAPL和Python相比优劣势在哪里现在不少HiL测试团队在推Python自动化框架用Python调用CANoe的COM接口来写测试用例。我理解这种趋势Python的库更丰富图表更漂亮维护起来对新人更友好。但作为在项目一线做了多年HiL测试的人我想说说CAPL的地位为何依然不可替代。核心原因在于CAPL运行在CANoe内部与总线事件的交互是实时的、无协议转换开销的。你用Python通过COM接口操作CANoe本质上走的是一条Python进程 → COM → CANoe引擎 → 总线的长链路。当测试用例对时序要求非常高时——比如需要精确在某个报文发送后的2ms内做出响应——Python的调度延迟和COM调用开销就容易让时序偏离预期。而CAPL是编译后运行在CANoe内部的事件触发到函数执行的延迟在微秒级能够满足很多实时性要求苛刻的场景。另外一个很现实的因素是很多老项目、老测试环境的测试序列已经用CAPL写好了几年甚至十几年维护这些脚本的工程师离职了新来的工程师如果不会CAPL连看都看不懂。企业招人把CAPL列进要求很大程度是要找一个接手就能干活的人而不是花时间先培训三个月的语言基础。不过我也得说句公道话现在新项目的趋势确实是Python和CAPL并存被测ECU的环境模拟、总线激励用CAPL做保证实时性测试管理、报告生成、数据可视化用Python做提高效率。两条腿走路是未来几年HiL测试团队的主流能力结构。所以不要问学CAPL还是学Python两个都要会。4. 从零到一的HiL测试项目实战CANoe和CAPL如何配合讲了这么多原理这一章我想用一个更整体的视角带你过一遍真实项目中HiL测试台上的CANoeCAPL是怎么配合完成工作的。会用到一个非常典型的例子整车控制器VCU的 HiL 测试开发。4.1 CANoe配置层工程文件和仿真环境的搭建一个HiL测试项目的CANoe工程绝不是一个新建的空白工程就完事了。一个可用性好的测试工程至少包含以下几个板块DBC数据库文件是整条总线通信的世界地图。DBC里定义了每个报文的ID、周期、长度、信号列表、信号缩放、离线判定等。HiL测试的项目初期DBC文件通常由网络设计部门和ECU供应商联合提供。你拿到DBC之后第一件事是仔细核对其准确性——我在项目中不止一次遇到过DBC里某个信号范围和通信矩阵不一致的情况导致后面每一条测试用例都在错误的基础上运行。**仿真节点Simulation Node**是你用CAPL实现的模拟ECU集合。在典型的VCU HiL测试里被测对象是VCU仿真节点就要包括电池管理系统BMS、电机控制器MCU、充电机OBC、仪表Cluster、车身控制器BCM等。每个仿真节点里都有一段CAPL代码负责按照DBC定义周期性地送出本节点的报文。为了方便管理我通常会把每个节点的仿真逻辑写在一个独立的CAPL文件里比如BMS_Sim.can、MCU_Sim.can然后在工程设置里统一挂载。**测试节点Test Module**是承载测试用例的仿真节点。它不参与假装ECU的工作而是专门执行测试序列、触发激励、监控响应、判定结果。在CANoe的Test Setup界面里你新建一个测试模块然后把编写好的自动化测试脚本挂进去。测试执行时CANoe会按照指定的顺序逐条运行测试用例并把每一步的执行结果记录到测试报告中。**面板Panel**是可选的但我强烈建议做。面板就相当于一个定制的可视化控制台上面放一些按钮、输入框、仪表盘控件方便测试工程师在调试阶段手动控制信号值。比如你可以放一个电池电压调节的滑动条一个钥匙上电按钮一个电机转速显示的仪表控件。这样在写正式脚本之前你可以用面板先手动试几遍确认ECU的行为符合预期再去编写标准化的自动化脚本。4.2 测试执行流程从手动试探到一键自动化一个典型的HiL测试用例执行流程是这样的手动调试阶段启动CANoe工程确认总线通信正常用面板手动调整关键信号观察ECU响应。这个阶段的主要目的是验证CANoe仿真节点和ECU的接线、参数匹配是否正常。CAPL测试用例编写阶段把手动调试时确定的行为逻辑转化为自动化测试脚本。比如钥匙切换到ON挡整车进入上电状态BMS发送主继电器闭合信号VCU收到后应允许电机控制器进入待机模式。这个逻辑在手动阶段已经跑通了现在把它变成CAPL代码配置好输入激励、时序等待、判定条件。测试套件执行阶段将多个测试用例组织成测试套件Test Suite一键启动执行。CANoe会按照顺序逐条跑用例遇到失败用例不会停下来——除非你在工程里配置了失败即停止。我在回归测试时通常配置为失败继续跑因为回归测试的目标是尽可能多地覆盖场景把所有失败项一起报告出来而不是卡在第一条就终止。4.3 测试结果自动判定的几个关键原则自动化测试最重要的环节不是跑起来而是判定合理。CAPL里提供了几个测试APITestStepPass()、TestStepFail()、TestWaitForTimeout()、TestWaitForMessage()等。这些API能帮你在脚本里精细控制测试节奏。但我见过很多新手工程师写测试判据时只判一个结果接收到了期望报文就算Pass没收到就算Fail。这种判定方式在真实项目里太粗放容易漏掉真正的缺陷。举一个真实的例子测试VCU的高压上下电时序时规范的时序是VCU收到钥匙ON信号后发出BMS主正继电器闭合请求 → 等待BMS反馈主正继电器状态为闭合 → 然后VCU才能允许电机控制器使能。如果你的测试只验证VCU是否发出继电器闭合请求而忽略了VCU是否等待BMS反馈后再驱动电机使能那么即使VCU没有遵守时序测试也会判定通过。这就是为什么测试用例设计阶段必须做预期结果的多维拆解——不仅要验证信号出现了还要验证信号出现的顺序、和关联信号的耦合关系、以及是否满足时间窗要求。CAPL里我经常用两个辅助手段来强化判据一是TestWaitForMessage带上超时参数来验证信号出现的时序二是在关键点之间检查gTestPass这类状态标志确保整个执行链路走到最后一步。4.4 从测试工程到标准规范的闭环测试项目结束以后CANoe工程本身是很好的知识资产。我所在的项目组在完成第一个VCU HiL测试项目后会把CANoe工程的目录结构、CAPL脚本命名规范、测试用例编号规则固化成内部标准。后面新项目接手时直接在这个标准框架下扩展能节省大量搭环境的时间。另外HiL测试中CAPL脚本的可维护性非常容易被低估。很多工程师写脚本的时候只顾眼前跑通变量命名用a、b、c函数体几百行不加注释将来某个变量取值范围要改动时往往得全文搜索猜测。好的CAPL脚本应该有清晰的模块划分、统一的命名规范、充分的注释并且把关键参数阈值、周期、地址提取到工程顶层的全局变量里。这样当设计变更时只需改一处定义而不需要逐条修改测试用例。5. CANoe和CAPL学习路径写给想进汽车测试岗的新人看到这里你应该已经理解了为什么汽车测试岗位会把CANoe和CAPL写进硬性要求。但光知道原理还不够如果你正在准备进入这个行业我基于自己的亲身体会给出几条学习路径建议。5.1 学习CANoe的最小必要清单CANoe是个功能非常庞大的工具如果什么都学很容易陷入一天打开软件发呆的状态。我的建议是先把这几样东西学扎实。第一是DBC文件的编辑与理解。DBC是CANoe操作的事实标准你要能看懂一条报文的ID如何定义、哪个信号放在哪个字节的哪个bit位、缩放因子和偏移量的含义。最好的练习方式是找几份真实车型的总线通信矩阵自己去对照DBC看报文。第二是Trace窗口和Graphics窗口的使用。你要能做到接到一个报文解析异常的问题不用猜直接在Trace里对比原始报文和DBC定义找出问题在哪——是发送端数据不对还是DBC解析设置错了。第三是总线统计和错误帧分析。总线上出现Bus-off、错误帧、ACK缺失意味着什么要能快速判断。很多ECU通信问题的根因不在ECU逻辑而在物理链路的质量CANoe的总线统计功能能在第一时间暴露这一类问题。第四是Logging。学会把测试过程中的报文完整记录下来并且能在事后回放、筛选、搜索。这是排查间歇性故障最重要的手段。我个人不建议一上来就啃官方手册。最好的方式是找一个开源的CANoe示例工程网上和Vector官方社区都有把里面的CAPL代码一行一行看明白然后试着改几个参数跑一跑。CANoe这个工具实操远比看书重要。5.2 学习CAPL的进阶路径CAPL的学习路径可以分四步走。第一步理解事件驱动模型。先写几个简单的例子——收到某条报文时打印一条日志定时器到点发一帧报文。把on message、on timer、on start这几个基础事件用熟。第二步掌握信号操作。学会用$信号名直接读取或设置DBC信号值掌握setSignal()、getSignal()这两个最常用的API。在此基础上做一个完整的剩余总线仿真节点——比如模拟一个BMS周期性发送电压、电流、SOC、绝缘电阻等报文。做这一步时你会体会到信号之间的关联性设计有多么重要。第三步引入测试机制。学习TestWaitForMessage、TestWaitForTimeout、TestCase、TestReport这些测试函数开始写带测试判据的自动化用例。这是从写仿真代码转向写测试代码的关键一步。第四步组件化和工程化。把常用逻辑抽取成函数库学会用include文件组织代码建立一套自己的CAPL标准库。我在个人工作中积累了一个MyCommonLib.can文件里面放了报文CRC校验、信号滤波去抖、诊断安全检查等通用函数新项目直接引用能省下大量时间。5.3 实战机会从哪里来很多同学卡在没有设备、没有软件这个环节。确实CANoe是商业软件配套的硬件VN16xx、VN89xx系列价格不低个人学习者很难承担。但我可以提供几个替代路径。第一个方向用Vector的免费评估版。Vector官网会提供CANoe的试用版而且部分功能比如纯软件仿真不接硬件是可以用的。你可以在试用期内把基本操作、CAPL脚本开发、仿真节点搭建全部都学会。第二个方向如果手头有树莓派、Arduino这类硬件可以用MCP2515模块搭建一个简单的CAN网络再用开源的cantools、python-can库配合自己设计一个小型的CAN通信系统。虽然和CANoe的成熟度没法比但足以帮你理解CAN总线的底层通信逻辑。第三个方向直接学zlg周立功的CAN卡和配套软件。国产CAN卡的价格比Vector低很多虽然生态和CANoe有差距但基础的总线报文收发、信号解析是完全一样的概念。先在这个环境下练手将来转到CANoe也能很快适应。我自己刚入行时也是从用免费的canoe demo版本开关软件看报文开始然后逐步接触真实项目的。这个行业有一点好只要你是真的付出了精力去实操面试官从你聊问题的细节深度就能判断出来。6. 写在最后的一些感想说到底CANoe和CAPL只是工具工具背后的核心价值是你对汽车电子系统的理解有多深。我见过会用CANoe熟练操作的人但对信号逻辑之间的耦合关系没有概念也见过CAPL写得很溜的人但让他分析一个问题报文的语义他回答不上来。工具和领域知识是相辅相成的只学其中一半在岗位上很快就会碰壁。对正在准备进入汽车测试行业的读者我想说如果你手头没有真实项目经验不用气馁很多岗位招聘时的熟练掌握CAPL并不是要求你有多年的实战积累而是希望你具备快速上手的能力和扎实的基础认知。把CANoe的工程结构、CAPL的事件模型、总线的信号概念吃透面试时能把这几个工具在实际项目中是怎么配合使用的讲清楚你已经赢过很多竞争者了。最后再分享一个我实际用过的小技巧。调试CAPL脚本时多利用write()函数和TestReport结合的方式把每一执行步骤的关键值打印出来。很多时候测试用例失败不是因为ECU真的有缺陷而是你的激励值没给对、时序没等到位、或者某个信号被总线上的其他节点打架了。有充分的日志才能快速定位到底是谁的问题。这个习惯已经成为我审查新同事测试用例时的第一条意见。
返回列表