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
相关产品推荐
相关产品推荐

