Bootstrap

【UDS诊断(WriteDataByIdentifier0x2E服务)测试用例CAPL代码全解析③】


ISO 14229-1:2023 UDS诊断【WriteDataByIdentifier0x2E服务】_TestCase03

作者:车端域控测试工程师
更新日期:2025年02月23日
关键词:UDS诊断协议、ECU复位服务、0x2E服务、ISO 14229-1:2023

TC2E-003测试用例

用例ID测试场景验证要点参考条款预期结果
TC2E-003数据长度不匹配数据记录长度与DID定义不一致§7.4.5.3.2返回NRC=0x13(报文长度错误)

一、测试逻辑设计

NRC=0x13
其他响应
超时
进入扩展会话
构造异常长度数据
发送0x2E写入请求
响应分析
测试通过
测试失败
判定通信故障

二、完整CAPL脚本

/* ================================================================= 
   TC2E-003 数据长度不匹配检测脚本(CANoe 12.0 SP2兼容)
   功能特性:
   - 动态数据长度生成 
   - 多维度NRC验证 
   - 自动环境恢复 
================================================================== */
 
variables {
  const long cDiagReqId = 0x727;           // 诊断请求ID 
  const word kValidDID = 0xF190;            // 已定义的标准DID 
  const byte kExpectedNRC = 0x13;          // 预期否定响应码 
  const dword kTimeout = 1500;             // 超时阈值(ms)
  const int kDefinedDataLength = 4;         // DID定义的标准数据长度 
  
  struct {
    byte currentSession;                  // 手动会话跟踪 
    byte invalidData[8];                  // 异常数据存储 
    mstimer recoveryTimer;                // 状态恢复计时器 
  } gState;
}
 
//  异常数据生成模块 
void GenerateInvalidData(int targetLength) {
  // 生成随机异常数据(长度不等于4)
  for(int i=0; i<elcount(gState.invalidData); i++) {
    gState.invalidData[i] = (i < targetLength) ? (byte)rand255() : 0x00;
  }
}
 
//  诊断服务封装模块 
void SendInvalidLengthRequest(int dataLength) {
  diagRequest WriteInvalid: 0x2E[kValidDID] data=gState.invalidData;
  diagSetParameterLength(WriteInvalid, dataLength);  // 强制设置异常长度 
  output(WriteInvalid);
}
 
//  主测试用例 
testcase TC2E_003_DataLengthMismatch() 
{
  // ████ 初始化阶段 ████ 
  testCaseTitle("TC2E-003 数据长度不匹配检测");
  gState.currentSession = 0x01;  // 初始默认会话 
  
  // ████ 阶段1:进入扩展会话 ████ 
  testStep("切换至扩展会话");
  diagRequest EnterExt: 0x10 0x03;
  output(EnterExt);
  if(TestWaitForDiagResponse(EnterExt, kTimeout) != 0) {
    testCaseAbort("会话切换失败");
  }
 
  // ████ 阶段2:构造异常数据 ████ 
  testStep("生成异常长度数据");
  int testCases[3] = {kDefinedDataLength-1, kDefinedDataLength+1, 0};
  for(int i=0; i<elcount(testCases); i++) {
    GenerateInvalidData(testCases[i]);
    
    // ████ 阶段3:发送异常请求 ████ 
    testStep("发送异常长度请求 [长度=%d]", testCases[i]);
    SendInvalidLengthRequest(testCases[i]);
    
    // ████ 阶段4:响应验证 ████ 
    testStep("验证否定响应");
    if(TestWaitForDiagResponse(WriteInvalid, kTimeout) == 0) {
      if(this.Response.Service == 0x7F && 
         this.Response.NegativeResponseCode == kExpectedNRC) {
        testStepPass("用例%d: 收到NRC=0x%02X", i+1, kExpectedNRC);
      } else {
        testCaseFail("异常响应 [SID=0x%02X NRC=0x%02X]", 
                    this.Response.Service, 
                    this.Response.NegativeResponseCode);
      }
    } else {
      testCaseFail("请求超时");
    }
  }
  
  // ████ 阶段5:恢复验证 ████ 
  testStep("ECU状态校验");
  diagRequest TesterPresence: 0x3E[0x00];
  output(TesterPresence);
  if(TestWaitForDiagResponse(TesterPresence, 1000) == 0) {
    testAddCondition("ECU运行状态正常");
  }
}
 
//  增强处理模块 
on diagResponse 0x7F.* {
  if(this.Request == WriteInvalid) {  // 目标请求过滤 
    testReportAddValue("异常长度测试结果", 
                      "长度:%d 收到NRC:0x%02X", 
                      diagGetParameterLength(this.Request),
                      this.NegativeResponseCode);
  }
}
 
on sysvar_update sysvar::Diag::CommStatus {
  // 总线状态监控 
  if(@sysvar::Diag::CommStatus == 0) {
    testCaseAbort("总线通信中断");
  }
}
 
on preStart {
  canSetBitrate(500, 3);         // 500kbps, 采样点75%
  diagSetDefaultTimeout(2000);   // 设置诊断默认超时 
}

三、测试执行流程

在CANoe Test Module中的操作序列 
-> setReportMode(extended)             # 启用扩展报告模式 
-> setIterationCount(3)                # 设置3种异常长度测试 
-> startTestCase(TC2E_003_DataLengthMismatch)

四、验证指标与结果分析

检查项合格标准验证方法
否定响应码一致性全部响应必须为0x13循环校验三个异常长度用例
数据长度容错性拒绝所有非标准长度数据边界值测试(0/3/5字节)
ECU稳定性测试后能正常响应0x3E服务附加心跳维持请求验证
时序符合性响应时间≤1500ms时间戳差值分析

五、兼容性说明

  1. API适配方案

    // 旧版本替代方案 
    #define diagWaitForResponse(req, timeout) TestWaitForDiagResponse(req, timeout)
    #define getActiveSession() sysvarGetInt(sysvar::Diag::Session)
    
  2. 硬件波形要求

    [Trigger]
    StartCondition = CAN.Message.ID == 0x727 
    StopCondition = CAN.Message.ID == 0x72F 
    PreTriggerTime = 100ms 
    
  3. 诊断数据库配置

    • 在CDD文件中需明确标注0xF190 DID的Data Length属性为4
    • 配置0x2E服务的动态长度校验参数为Strict

六、高级调试建议

  1. 异常注入增强

    // 在GenerateInvalidData中增加特殊模式 
    case 1:  // 全零模式 
      memset(gState.invalidData, 0x00, sizeof(gState.invalidData));
    case 2:  // 随机填充模式 
      randomize(gState.invalidData);
    
  2. 自动化报告生成

    testReportAddGraph("NRC分布", 
                      "0x13=%d; 其他=%d", 
                      countNRC(0x13), 
                      totalCount - countNRC(0x13));
    

结尾请关注

关注作者,后续连载更多汽车电子测试知识栏目,包括不限于:汽车控制器测试全流程解析、常见故障排查案例、测试工具深度教程、行业协议解读、行业前沿与职业发展之《2024年汽车电子测试工程师必备技能TOP10:掌握Python自动化测试年薪涨5W?》、《汽车控制器测试工程师面试指南:如何用STAR法则拿下30W Offer?》、《零基础玩转汽车电子测试:从CANoe到HIL实战》、《CANoe自动化测试框架(支持XCP标定+UDS诊断)》

;