You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CAPL中diagSetSuppressResp函数使用及TesterPresent阻塞问题求助

问题:UDS TesterPresent抑制正响应时CANoe阻塞问题

编写CAPL脚本自动化测试UDS的TesterPresent服务,需要发送设置了suppressPosRspMsgIndicationBit(抑制正响应消息指示位)的请求,可通过diagSetParameter(Req_0x3E,"zeroSubFunction",0x80)实现。但遇到以下问题:

  • 多条测试用例顺序执行时,发送带抑制位的TesterPresent请求后,被测ECU无响应(符合预期),但CANoe会一直等待ISO TP诊断层的P2客户端定时器超时
  • 超时期间CANoe会阻塞所有UDS请求(包括诊断控制台的手动请求),testWaitForDiagRequestSent返回错误码,导致后续测试用例无法发送请求
  • 不想调整P2客户端定时器,尝试用diagSetSuppressResp函数处理,但问题依旧,求该函数的正确用法或替代解决方案

原代码

完整代码片段

includes
{
}
variables
{
  //zeroSubFunction
  const byte zeroSubFunction_False = 0x00;
  const byte zeroSubFunction_True = 0x80;
  const byte ISOSAEReserved_0x3E = 0x01;
  
  //Diagnostic objects
  diagRequest BasicDiagnosticsEcu.UDS_Diagnostic_Services_Generic.TesterPresent_Process Req_0x3E;
  diagResponse BasicDiagnosticsEcu.UDS_Diagnostic_Services_Generic.TesterPresent_Process Resp_0x3E;
}
void service0x3E_req(byte expected_NRC,byte session_req)
{
  long ret;
  long ret1;
  diagInitialize(Req_0x3E);
  //diagSetParameter(Req_0x3E,"zeroSubFunction",session_req);
  if(session_req == zeroSubFunction_True)
  {
    diagSetTarget("BasicDiagnosticsEcu");
    ret1 = diagsetSuppressResp(Req_0x3E,1);
    testStep("","Debug ret = %d",ret1);
  }
  else if(session_req == zeroSubFunction_False)
  {
    diagSetTarget("BasicDiagnosticsEcu");
    ret1 = diagsetSuppressResp(Req_0x3E,0);
    testStep("","Debug ret = %d",ret1);
  }
  else diagSetParameter(Req_0x3E,"zeroSubFunction",session_req);
  
  ret = sendDiagObject(Req_0x3E);
  
  
  if(ret == 0)
  {
    if(session_req == zeroSubFunction_True)
    {
      testStepPass("","No response received when request for zeroSubFunction: 0x%02X",session_req);
      //testWaitForTimeout(10000);
      return;
    }
    else testStepFail("","No response received!");
  }
}

简化测试用例代码

testcase tc()
{
  long ret;
  diagInitialize(Req_0x3E);
  diagsetSuppressResp(Req_0x3E,1);
  diagSendRequest(Req_0x3E);
  ret = testWaitForDiagRequestSent(Req_0x3E,2000);
    if (ret == 1) 
    {
      testStepPass("Tx","-	Successfully send Diagnostic request message.");
    }
    else
    {
      TestStepFail("Tx","-	Diagnostic request timeout error! Error code: %ld",ret);
    }
  diagInitialize(Req_0x3E);
  diagsetSuppressResp(Req_0x3E,0);
  diagSendRequest(Req_0x3E);
  ret = testWaitForDiagRequestSent(Req_0x3E,2000);
    if (ret == 1) 
    {
      testStepPass("Tx","-	Successfully send Diagnostic request message.");
    }
    else
    {
      TestStepFail("Tx","-	Diagnostic request timeout error! Error code: %ld",ret);
    }
}

解决方案

1. diagSetSuppressResp的正确用法

该函数需要在设置请求参数之后、发送请求之前调用,且仅对当前初始化的请求实例生效。原代码中未先设置zeroSubFunction参数就调用该函数,导致配置不生效。

2. 调整发送与等待逻辑

发送带抑制响应的请求时,不要使用testWaitForDiagRequestSent(该函数会等待响应完成),只需检查请求是否发送成功,并主动释放请求上下文避免阻塞。

修正后的代码示例

testcase tc()
{
  long ret;
  
  // 发送带抑制响应的TesterPresent请求
  diagInitialize(Req_0x3E);
  // 先设置抑制位参数
  diagSetParameter(Req_0x3E, "zeroSubFunction", zeroSubFunction_True);
  // 再启用响应抑制
  diagSetSuppressResp(Req_0x3E, 1);
  // 发送请求
  ret = diagSendRequest(Req_0x3E);
  
  if (ret == 0) 
  {
    testStepPass("Tx", "- 成功发送带抑制响应的TesterPresent请求");
    // 主动释放请求资源,避免CANoe持续等待P2超时
    diagCancelRequest(Req_0x3E);
  }
  else
  {
    TestStepFail("Tx", "- 发送抑制响应请求失败!错误码: %ld", ret);
  }

  // 发送正常TesterPresent请求
  diagInitialize(Req_0x3E);
  diagSetParameter(Req_0x3E, "zeroSubFunction", zeroSubFunction_False);
  diagSetSuppressResp(Req_0x3E, 0);
  ret = diagSendRequest(Req_0x3E);
  
  // 正常请求需要等待响应
  ret = testWaitForDiagRequestSent(Req_0x3E, 2000);
  if (ret == 1) 
  {
    testStepPass("Tx", "- 成功发送正常TesterPresent请求");
  }
  else
  {
    TestStepFail("Tx", "- 正常请求超时!错误码: %ld", ret);
  }
}

关键注意事项

  • diagSetSuppressResp的配置是一次性的,每次发送请求前都需要重新设置
  • 发送抑制响应的请求后,调用diagCancelRequest可以立即释放CANoe的诊断会话上下文,避免阻塞后续请求
  • 抑制响应场景下,无需等待响应,只需验证请求是否成功发送即可

内容的提问来源于stack exchange,提问作者Dragoni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 12:42:46