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 | 维持会话的最小间隔 |
响应状态矩阵
复位类型 | 预期结果 | 失败模式示例 |
---|---|---|
硬件复位 | 立即执行 | 系统未实际断电 |
钥匙复位 | 点火周期复位 | 未检测到钥匙信号 |
软件复位 | 应用层重启 | 部分进程未终止 |
工业级增强功能
-
复位深度检测
cpp// 通过系统变量验证复位层级 on sysvar ECU::ResetLevel { testAddLog("当前复位深度:%d级", @this::ResetLevel); }
-
混合负载测试
cppvoid ExecuteStressTest() { // 可扩展: // 1. 随机顺序执行复位类型 // 2. 叠加总线负载(70%-90%) // 3. 电源波动模拟 }
-
时序校验逻辑
cpp// 验证响应时序合规性 if(getTimer(responseTimer) < 200) { testAddCondition("响应时间:%dms", getTimer(responseTimer)); }
测试执行说明
-
环境配置建议
ini[Diagnostic] P2Server_Timeout = 3000 P2Client_Timeout = 5000
-
结果判定标准
检查项 合格标准 验证方法 会话保持 100%维持扩展会话 日志分析 复位独立性 各类型执行成功率100% 状态机验证 时序符合性 误差≤±15% 示波器测量
专家调试技巧:
在
Write
窗口添加过滤条件:
bashid==733h && (byte(0)==51h || byte(0)==7Fh)
使用
Graphic
窗口监控信号:
inisysvar::ECU::PowerStatus sysvar::Diag::ActiveSession
添加总线触发条件:
cppon message DiagResID { if(this.byte(0) == 0x7F) break; }