【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析⑩】

ISO 14229-1:2023 UDS诊断【ECU复位0x11服务】_TestCase10

作者:车端域控测试工程师

更新日期:2025年02月18日

关键词:UDS诊断协议、ECU复位服务、0x11服务、ISO 14229-1:2023

TC11-010测试用例

用例ID 测试场景 验证要点 参考条款 预期结果
TC11-010 混合复位类型执行 在扩展会话中交替请求不同复位类型 §8.2.5 各复位类型独立生效无冲突

以下是为TC11-010设计的工业级CAPL测试用例,包含多复位类型状态机验证,包含时序控制策略和异常处理机制:

cpp 复制代码
/*----------------------------------------------------------
  Title:TC11-010 混合复位类型冲突验证 
  作者:车端域控测试工程师 
  日期:2025-02-18 
------------------------------------------------------------*/
 
variables {
  // 通信参数 
  const long DiagReqID = 0x732;       // 诊断请求标识符 
  const long DiagResID = 0x733;       // 诊断响应标识符 
  const byte SessionCtrlSID = 0x10;   // 会话控制服务 
  const byte ResetSID = 0x11;         // ECU复位服务 
  
  // 复位类型配置(基于OEM规范)
  struct sResetType {
    byte subFunc;    // 子功能号 
    char* desc;      // 类型描述 
    dword delay;     // 预期执行时间 
  } resetTypes[3] = {
    {0x01, "硬件复位", 1200},
    {0x02, "钥匙复位", 800},
    {0x03, "软件复位", 500}
  };
  
  // 动态控制变量 
  msTimer sessionTimer;
  int currentResetIndex = 0;
  byte responseStatus[3];             // 0-未响应 1-成功 2-失败 
}
 
testcase TC11_010_MixedResetTest() 
{
  TestModuleTitle("TC11-010 混合复位类型冲突验证");
  
  // ███ 阶段1:进入扩展会话 ███ 
  testStep("STEP1 进入扩展诊断会话");
  message DiagReqID [CAN] {
    dlc = 2;
    byte(0) = SessionCtrlSID;
    byte(1) = 0x03;  // 扩展会话 
  }
  output(this);
  
  if(TestWaitForMessage(DiagResID, 200) && 
     this.byte(0) == 0x50 && 
     this.byte(1) == 0x03) 
  {
    testStepPass("成功进入扩展会话");
    setTimer(sessionTimer, 5000);  // 会话保活计时 
  } else {
    testStepFail("会话建立失败");
    return;
  }
 
  // ███ 阶段2:交替执行复位操作 ███ 
  testStep("STEP2 执行混合复位序列");
  for(currentResetIndex=0; currentResetIndex<3; currentResetIndex++)
  {
    // 发送复位请求 
    message DiagReqID [CAN] {
      dlc = 2;
      byte(0) = ResetSID;
      byte(1) = resetTypes[currentResetIndex].subFunc;
    }
    output(this);
    
    // 响应处理窗口 
    if(TestWaitForMessage(DiagResID, 300)) 
    {
      // 肯定响应验证 
      if(this.byte(0) == 0x51 && 
         this.byte(1) == resetTypes[currentResetIndex].subFunc) 
      {
        responseStatus[currentResetIndex] = 1;
        testAddLog("%s 执行成功", resetTypes[currentResetIndex].desc);
        
        // 等待复位完成 
        testWait(resetTypes[currentResetIndex].delay);
        
        // 重新激活会话 
        message DiagReqID [CAN] {
          dlc = 2;
          byte(0) = SessionCtrlSID;
          byte(1) = 0x03;
        }
        output(this);
        TestWaitForMessage(DiagResID, 200);
      }
      // 否定响应处理 
      else if(this.byte(0) == 0x7F && 
              this.byte(1) == ResetSID) 
      {
        responseStatus[currentResetIndex] = 2;
        testAddLog("%s 执行失败(NRC=0x%02X)", 
                  resetTypes[currentResetIndex].desc, this.byte(2));
      }
    }
    else 
    {
      responseStatus[currentResetIndex] = 0;  // 超时 
    }
    
    // 操作间隔 
    testWait(300);
  }
 
  // ███ 阶段3:综合结果验证 ███ 
  testStep("STEP3 验证独立生效性");
  int successCount = 0;
  for(int i=0; i<3; i++) 
  {
    if(responseStatus[i] == 1) {
      testStepPass("%s 独立生效", resetTypes[i].desc);
      successCount++;
    } else {
      testStepFail("%s 状态异常(代码:%d)", 
                  resetTypes[i].desc, responseStatus[i]);
    }
  }
  
  if(successCount == 3) {
    testCasePass("所有复位类型独立生效");
  } else {
    testCaseFail("检测到%02d/03次冲突", successCount);
  }
}
 
/*----------------------------------------------------------
  会话状态监控模块(关键扩展)
----------------------------------------------------------*/
on timer sessionTimer 
{
  testAddCondition("会话保活剩余时间:%.1fs", 
                  (5000 - getTimer(sessionTimer))/1000.0);
  
  // 每4秒发送TesterPresent 
  if(getTimer(sessionTimer) % 4000 == 0) {
    message DiagReqID [CAN] {
      byte(0) = 0x3E;  // TesterPresent 
      byte(1) = 0x00;
    }
    output(this);
  }
}

流程图解(执行逻辑可视化)
进入扩展会话 发送0x11 0x01
等待1200ms 发送0x11 0x02
等待800ms 发送0x11 0x03
等待500ms 结果验证

关键参数说明表

参数名称 示例值 工程校准要点
会话保活周期 5000ms 需小于ECU会话超时时间
复位执行延迟 类型相关 根据OEM标定值调整
操作间隔 300ms 需覆盖总线负载高峰期
TesterPresent周期 4000ms 维持会话的最小间隔

响应状态矩阵

复位类型 预期结果 失败模式示例
硬件复位 立即执行 系统未实际断电
钥匙复位 点火周期复位 未检测到钥匙信号
软件复位 应用层重启 部分进程未终止

工业级增强功能

  1. 复位深度检测

    cpp 复制代码
    // 通过系统变量验证复位层级 
    on sysvar ECU::ResetLevel {
      testAddLog("当前复位深度:%d级", @this::ResetLevel);
    }
  2. 混合负载测试

    cpp 复制代码
    void ExecuteStressTest() {
      // 可扩展:
      // 1. 随机顺序执行复位类型 
      // 2. 叠加总线负载(70%-90%)
      // 3. 电源波动模拟 
    }
  3. 时序校验逻辑

    cpp 复制代码
    // 验证响应时序合规性 
    if(getTimer(responseTimer) < 200) {
      testAddCondition("响应时间:%dms", getTimer(responseTimer));
    }

测试执行说明

  1. 环境配置建议

    ini 复制代码
    [Diagnostic]
    P2Server_Timeout = 3000 
    P2Client_Timeout = 5000 
  2. 结果判定标准

    检查项 合格标准 验证方法
    会话保持 100%维持扩展会话 日志分析
    复位独立性 各类型执行成功率100% 状态机验证
    时序符合性 误差≤±15% 示波器测量

专家调试技巧:

  1. Write窗口添加过滤条件:

    bash 复制代码
    id==733h && (byte(0)==51h || byte(0)==7Fh)
  2. 使用Graphic窗口监控信号:

    ini 复制代码
    sysvar::ECU::PowerStatus 
    sysvar::Diag::ActiveSession 
  3. 添加总线触发条件:

    cpp 复制代码
    on message DiagResID {
      if(this.byte(0) == 0x7F) break;
    }
相关推荐
_dindong15 分钟前
笔试强训:Week -2
笔记·学习·算法
deng-c-f36 分钟前
Linux C/C++ 学习日记(26):KCP协议(二):kcp源码分享
c语言·c++·学习·网络编程·kcp
雾岛听蓝1 小时前
深入解析内存中的整数与浮点数存储
c语言·经验分享·笔记·visualstudio
Yupureki1 小时前
从零开始的C++学习生活 9:stack_queue的入门使用和模板进阶
c语言·数据结构·c++·学习·visual studio
小年糕是糕手1 小时前
【数据结构】单链表“0”基础知识讲解 + 实战演练
c语言·开发语言·数据结构·c++·学习·算法·链表
聪明的笨猪猪1 小时前
Java JVM “垃圾回收(GC)”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
半夏知半秋2 小时前
lua对象池管理工具剖析
服务器·开发语言·后端·学习·lua
CoookeCola2 小时前
Google Landmarks Dataset v2 (GLDv2):面向实例级识别与检索的500万图像,200k+类别大规模地标识别基准
图像处理·人工智能·学习·目标检测·计算机视觉·视觉检测
syt_biancheng2 小时前
C++ 多态(1)
jvm·c++·学习
ue星空3 小时前
逆向分析光与影:33号远征队使用的UE技术栈
笔记·学习