尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

基于CANoe的UDS诊断测试:从0x10服务用例设计到自动化实现

基于CANoe的UDS诊断测试:从0x10服务用例设计到自动化实现 在汽车电子开发与测试领域诊断功能是确保ECU电子控制单元软件质量、实现故障排查和在线刷写的关键。UDSUnified Diagnostic Services统一诊断服务协议ISO 14229定义了标准化的诊断服务而Vector CANoe则是实现这些服务仿真、测试和验证的核心工具。很多工程师在接触CANoe进行UDS测试时往往直接开始编写CAPL脚本却忽略了最基础也最重要的一步如何根据具体的诊断需求系统化地设计出覆盖全面、逻辑清晰的测试用例。一个设计不当的测试集要么遗漏关键场景导致线上问题要么用例冗余浪费测试资源。本文将以一个具体的诊断服务——0x10诊断会话控制Diagnostic Session Control为例详细拆解从需求分析到用例设计的完整过程。我们将深入探讨0x10服务的协议细节、状态机转换逻辑并重点讲解如何在CANoe环境中利用CAPL脚本、诊断描述文件如CDD/ODX和Test Feature Set模块将设计好的用例转化为可执行、可自动化、可报告的测试工程。无论你是刚接触UDS诊断测试的新手还是希望提升测试用例设计系统性的工程师本文提供的思路和实操步骤都将为你提供一个清晰的指引。1. 理解0x10诊断会话控制服务的核心机制在设计测试用例之前必须透彻理解被测对象的工作原理。0x10服务并非一个简单的命令它管理着ECU诊断状态的生命周期是其他大多数诊断服务得以执行的前提。1.1 服务功能与子服务定义根据ISO 14229-10x10服务用于控制ECU内部不同的诊断会话。其主要目的是在不同的会话模式下启用或禁用特定的诊断功能集。例如默认会话Default Session可能只支持读取数据而编程会话Programming Session则必须启用安全访问和电写功能。该服务包含一个必选参数subFunction子功能用于指定目标会话。常见的子功能值包括0x01- 默认会话DefaultSession0x02- 编程会话ProgrammingSession0x03- 扩展诊断会话ExtendedDiagnosticSession此外该服务还有一个可选参数sessionParameterRecord可用于传递会话特定的信息例如安全等级或超时时间但大多数基础实现中此参数为空。1.2 会话状态机与时间参数ECU内部维护着一个诊断会话状态机。这是设计用例的逻辑核心。状态转换通常遵循以下规则ECU上电后自动进入默认会话0x01。在默认会话下可以切换到编程会话0x02或扩展会话0x03。在非默认会话下可以切换到其他非默认会话也可以切换回默认会话。每个非默认会话都有一个关联的P2Server_max服务器端响应超时和S3Server会话保持时间定时器。如果在S3Server时间内未收到任何诊断请求包括0x3E TesterPresent服务ECU应自动回退到默认会话。理解这个状态机和定时器机制是设计“有效转换”、“无效转换”、“超时处理”等用例类别的基础。例如测试“从编程会话超时自动回退到默认会话”就是一个基于状态机和时间参数的典型用例。1.3 肯定响应与否定响应0x10服务的肯定响应Positive Response格式为50 subFunction表示会话切换成功。否定响应Negative Response则遵循7F 10 NRC的格式其中NRCNegative Response Code指明了失败原因。与0x10服务相关的常见NRC包括0x12- 子功能不支持sub-functionNotSupported0x13- 报文长度或格式错误incorrectMessageLengthOrInvalidFormat0x22- 条件不满足conditionsNotCorrect例如在车辆行驶时尝试进入编程会话。0x7E- 子功能在当前会话中不支持subFunctionNotSupportedInActiveSession这是一个极易混淆的NRC它并不意味着ECU完全不支持该子功能而是指在当前激活的会话下不能切换到目标会话。例如规范可能禁止从扩展会话直接跳转到编程会话。2. 基于需求拆解测试点与设计用例“根据需求设计用例”意味着我们需要将协议文本、功能规范中的描述转化为一个个可验证的测试项。下面我们以一个假设的ECU诊断规范为例展示如何系统地进行拆解。2.1 需求分析与测试点提取首先我们收集所有与0x10服务相关的需求。这些需求可能来自ISO 14229-1 协议标准定义了服务的通用行为。OEM诊断规范定义了车辆制造商特定的参数如S3Server时间、允许的会话转换路径。ECU软件需求文档SRD定义了本ECU特有的行为如“当车速5km/h时禁止进入编程会话”。假设我们有以下几条简化需求Req-1: ECU应支持默认会话0x01、编程会话0x02和扩展会话0x03。Req-2: 上电后ECU应自动进入默认会话。Req-3: 在默认会话下可以切换到编程或扩展会话。Req-4: 在编程或扩展会话下可以切换回默认会话。Req-5: 在扩展会话下禁止直接切换到编程会话应返回NRC 0x7E。Req-6: 编程会话的S3Server时间应为5000ms。Req-7: 当车辆速度信号 5 km/h时请求进入编程会话应被拒绝NRC 0x22。从这些需求中我们可以提取出多个测试点Test PointTP1: 上电后自动进入默认会话的验证。TP2: 有效会话转换路径的验证如 01-02, 01-03, 02-01, 03-01。TP3: 无效会话转换路径的验证如 03-02。TP4: 请求不支持的子功能如0x04应返回NRC 0x12。TP5: 错误格式报文如长度错误应返回NRC 0x13。TP6: 编程会话下无0x3E服务保持时应在5000ms后自动回退到默认会话。TP7: 模拟车速5km/h时请求进入编程会话应返回NRC 0x22。2.2 测试用例设计模板为每个测试点设计详细的测试用例。一个好的测试用例应包含以下要素用例ID测试目标前置条件测试步骤预期结果判定标准UC-10-01验证上电后ECU处于默认会话1. ECU硬线断电。2. CANoe工程加载正确DBC/CDD文件。1. 给ECU上电。2. 通过CANoe Diagnostic Console发送10 01诊断会话控制请求。ECU回复肯定响应50 01。响应报文为50 01。UC-10-02验证从默认会话切换到编程会话ECU处于默认会话。发送请求10 02。ECU回复肯定响应50 02。响应报文为50 02。UC-10-03验证从扩展会话切换到编程会话被禁止ECU处于扩展会话已通过10 03进入。发送请求10 02。ECU回复否定响应7F 10 7E。响应NRC为0x7E。UC-10-04验证编程会话超时机制1. ECU处于编程会话。2. 停止发送3E服务。1. 进入编程会话。2. 等待5500ms略大于S3时间。3. 发送10 01请求。1. 等待期间无响应。2. 步骤3的请求应收到50 01。能成功切回默认会话证明超时已发生。UC-10-05验证车速条件对进入编程会话的影响1. ECU处于默认会话。2. 模拟发送车速信号值5km/h。发送请求10 02。ECU回复否定响应7F 10 22。响应NRC为0x22。这个表格将抽象的测试点转化为了可执行、可验证的具体操作指令和预期结果是连接需求与自动化脚本的桥梁。3. 在CANoe环境中搭建测试工程与实现用例设计好用例后下一步是在CANoe中将其实现。我们将创建一个结构清晰的测试工程。3.1 工程环境准备与诊断描述文件导入创建CANoe工程新建一个CANoe工程根据ECU硬件设置正确的通道、波特率如CAN, 500kbps。导入网络描述文件导入DBC文件定义CAN信号如车速VehicleSpeed。导入诊断描述文件这是最关键的一步。将ECU的CDD或ODX文件导入CANoe的Diagnostic/ISO TP配置中。正确导入后CANoe能解析服务标识符、请求响应格式、会话状态机、时间参数P2Server_max和S3Server等。你可以在Diagnostic Console中直接使用服务名而非原始字节来发送请求。3.2 使用CAPL脚本实现自动化测试逻辑对于UC-10-04超时测试和UC-10-05条件判断测试需要编写CAPL脚本实现自动化。示例实现UC-10-05车速条件判断测试// CAPL Script: CheckSessionSwitchWithSpeedCondition variables { msTimer waitTimer; message CAN1.::EngineData speedMsg; // 假设车速信号在EngineData报文里 float currentSpeed 0; } // 模拟发送车速信号在另一个仿真节点或定时器中 on timer waitTimer { currentSpeed 10.0; // 设置为10 km/h大于5 speedMsg.VehicleSpeed currentSpeed; // 赋值给DBC中定义的信号 output(speedMsg); } // 主测试函数可由Test Module或面板按钮调用 testcase TC_10_05_SpeedCondition() { diagRequest DefaultSessionReq diagRequest; // 声明诊断请求对象 diagResponse resp; byte nrc; // 步骤1确保在默认会话 DiagSetTargetSession(DEFAULT_SESSION); // 这是一个CAPL诊断API用于设置目标会话 TestWaitForDiagResponse(DefaultSessionReq, resp, 2000); // 等待响应 // 步骤2启动车速模拟 setTimer(waitTimer, 100); // 100ms后开始发送车速 TestWaitForTimeout(150); // 等待一下确保信号已发出 // 步骤3尝试进入编程会话 diagRequest ProgrammingSessionReq; // 根据CDD生成的请求对象 DiagSendRequest(ProgrammingSessionReq); // 步骤4检查响应 if (TestWaitForDiagResponse(ProgrammingSessionReq, resp, 2000)) { // 收到了响应 if (DiagIsNegativeResponse(resp, nrc)) { // 检查是否为NRC 0x22 if (nrc 0x22) { TestStepPass(UC-10-05, Correctly received NRC 0x22 when speed 5km/h.); } else { TestStepFail(UC-10-05, Received NRC 0x%02X, but expected 0x22., nrc); } } else { TestStepFail(UC-10-05, Unexpected positive response received.); } } else { TestStepFail(UC-10-05, No diagnostic response received.); } // 步骤5清理停止车速模拟 cancelTimer(waitTimer); currentSpeed 0; speedMsg.VehicleSpeed currentSpeed; output(speedMsg); }关键解释diagRequest和diagResponse是CAPL中基于CDD文件的高级诊断对象使用它们比直接拼写字节更可靠、更易读。TestWaitForDiagResponse是Test Feature Set中的函数用于同步等待诊断响应非常适合测试用例流程控制。通过操作DBC中定义的信号VehicleSpeed来模拟网络环境这是实现条件测试的常用方法。3.3 利用Test Feature Set组织测试序列对于多个用例我们使用CANoe的Test Feature Set来组织和管理。创建Test Unit在Test Setup中创建一个Test Unit。添加Test Cases将写好的CAPL测试函数如TC_10_05_SpeedCondition作为Test Case添加到Test Unit中。配置测试序列可以设置用例的执行顺序、依赖关系。集成诊断参数在Test Configuration中关联之前导入的诊断描述文件这样测试用例就能正确识别服务。生成测试报告运行测试序列后CANoe会自动生成详细的HTML或XML报告包含每个测试步骤的通过/失败状态、日志信息这对于问题追溯和测试证明至关重要。4. 关键验证、常见问题排查与最佳实践将用例脚本化并执行后验证和排查是确保测试有效性的最后一步。4.1 验证测试的有效性正向用例验证确保在正确条件下能收到肯定响应50 xx并且ECU的实际行为符合预期如某些功能被激活。负向用例验证确保在错误条件错误格式、错误状态、错误参数下ECU返回了正确的NRC而不仅仅是任意一个NRC。这是测试严谨性的体现。时间参数验证对于S3Server超时测试需要使用CANoe的Trace窗口或Write窗口精确测量时间。可以发送3E服务来“续命”观察会话保持停止发送后等待特定时间再尝试会话切换验证超时是否发生。状态机验证通过连续发送一系列设计好的请求验证ECU的会话状态转换图是否与规范完全一致。可以使用CAPL脚本自动遍历所有合法和非法的转换路径。4.2 常见问题与排查路径在CANoe中执行UDS测试时经常会遇到以下问题问题现象可能原因排查步骤发送诊断请求后无任何响应1. 物理连接或通道配置错误。2. CAN ID配置错误请求/响应ID未配对。3. ISO-TP层参数如寻址方式、帧类型配置与ECU不匹配。4. ECU未上电或未进入可诊断状态。1. 检查CANoe硬件通道灯、ECU供电。2. 在Trace窗口查看请求报文是否成功发出。3. 核对CDD文件中的Request ID和Response ID与CANoe配置是否一致。4. 检查ISO-TP的Functional或Physical寻址设置。收到否定响应NRC 0x10通用拒绝通常意味着ECU处于繁忙状态或发生底层通信故障。1. 检查ECU是否正在处理其他高优先级任务如刷写。2. 检查CAN总线负载率是否过高。3. 尝试增加P2Client客户端等待响应时间。收到否定响应NRC 0x7E子功能在当前会话中不支持。1.确认当前激活的会话通过发送3E 00TesterPresent并观察响应或发送10 01看是否返回50 01来判断。2.核对规范确认试图执行的会话转换是否被允许。这是设计用例时需要重点覆盖的场景。测试用例间歇性失败1. 定时器竞争条件。2. 环境信号干扰如车速信号突然变化。3. 未考虑ECU的初始化和稳定时间。1. 在测试步骤间增加合理的testWaitForTimeout等待。2. 在用例开始前强制设置相关环境信号到一个确定状态。3. 上电后等待足够时间如2秒再进行首次诊断通信。CAPL脚本中diagRequest对象报错“未定义”未正确关联诊断描述文件或对象名称拼写错误。1. 在CAPL编辑器的Symbols窗口中检查Diagnostic目录下是否有导入的服务对象。2. 确保CAPL节点的Diagnostic Description属性已关联正确的CDD文件。3. 对象名称需与CDD文件中定义的服务名完全一致。4.3 测试设计与执行的最佳实践用例设计先行在动手写CAPL脚本之前务必完成详细的测试用例设计文档如表格式。这有助于团队评审和覆盖度评估。利用诊断描述文件始终坚持使用CDD/ODX文件来生成诊断对象避免硬编码服务ID和参数。这能极大提高脚本的可维护性和对协议变更的适应性。分离测试逻辑与测试数据考虑将测试用例的输入如请求子功能、预期NRC、超时时间存储在外部文件如Excel、.csv中。CAPL脚本读取文件并驱动测试。这样新增用例时只需修改数据文件无需改动脚本。模拟完整的测试环境除了诊断通信还要模拟ECU依赖的网络信号如车速、点火状态、输入输出等。这确保了测试的“系统级”真实性。实现自动化测试序列将单个测试用例组织成完整的测试序列实现一键执行、自动判断、报告生成。这是提升回归测试效率的关键。重视测试报告分析测试报告不仅是看通过率更要关注失败用例的日志。详细的日志包括发送的原始报文、接收的原始报文、时间戳、环境变量值是定位问题的宝贵信息。版本化管理对CANoe工程、CAPL脚本、CDD文件、测试用例设计文档进行版本控制如Git确保测试资产与ECU软件版本严格对应。从理解0x10服务的协议细节和状态机开始到系统化地提取测试点、设计结构化用例最后在CANoe中通过CAPL脚本和Test Feature Set实现自动化验证这是一个完整的UDS诊断测试工作流。掌握这个方法论不仅能用于0x10服务更能推广到其他UDS服务如0x27安全访问、0x2E写数据、0x31例程控制等的测试设计中。真正的挑战往往不在于工具的使用而在于对需求的深刻理解和对测试场景的周密考虑。在后续的实践中可以尝试将这里展示的模板扩展到更复杂的服务并探索与持续集成CI系统的结合构建更强大的自动化诊断测试体系。
返回列表