【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;
    }
相关推荐
小王努力学编程21 分钟前
美团2024年春招第一场笔试 C++
开发语言·数据结构·c++·学习·算法
卡皮巴拉爱吃小蛋糕24 分钟前
MySQL的事务(Transaction)【学习笔记】
数据库·笔记·学习·mysql
superior tigre25 分钟前
C++学习:六个月从基础到就业——STL算法(一) 基础与查找算法
c++·学习·算法
一RTOS一1 小时前
鸿道操作系统Type 1虚拟化:破局AI机器人与智能汽车的“安全”与“算力”双刃剑
人工智能·机器人·汽车·鸿道intewell操作系统·工业os
gbase_lmax2 小时前
gbase8s存储学习一 rootdbs存储结构以及寻址分析
数据库·学习
guts3503 小时前
【pytorch学习】土堆pytorch笔记1
pytorch·笔记·学习
笺上山河梦3 小时前
C++ 的 输入输出流(I/O Streams)
开发语言·c++·学习·算法
zhuyixiangyyds3 小时前
day35图像处理OpenCV
图像处理·笔记·学习
程序员三藏5 小时前
Python+Selenium的自动化测试框架详解
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
小浪学编程5 小时前
C#学习1_认识项目/程序结构
开发语言·前端·学习·c#·游戏引擎