【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;
    }
相关推荐
安 当 加 密1 小时前
守护汽车“空中升级“:基于HSM/KMS的安全OTA固件签名与验证方案
安全·汽车
武子康6 小时前
Java-82 深入浅出 MySQL 内部架构:服务层、存储引擎与文件系统全覆盖
java·开发语言·数据库·学习·mysql·spring·微服务
Joker—H9 小时前
【Java】Reflection反射(代理模式)
java·开发语言·经验分享·代理模式·idea
霜绛10 小时前
机器学习笔记(三)——决策树、随机森林
人工智能·笔记·学习·决策树·随机森林·机器学习
站住前面的二哈11 小时前
Cartographer安装测试与模块开发(三)--Cartographer在Gazebo仿真环境下的建图以及建图与定位阶段问题(实车也可参考)
学习·ubuntu
★YUI★11 小时前
学习游戏制作记录(克隆技能)7.25
学习·游戏·unity·c#
屁股割了还要学12 小时前
【C语言进阶】柔性数组
c语言·开发语言·数据结构·c++·学习·算法·柔性数组
woodykissme13 小时前
UG创建的实体橘黄色实体怎么改颜色?
学习·齿轮·ug建模
Feather_7413 小时前
从Taro的Dialog.open出发,学习远程控制组件之【事件驱动】
javascript·学习·taro
星仔编程14 小时前
python学习DAY22打卡
学习