Autosar网络管理测试用例 - TC001
| 项目 | 内容 |
|---|---|
| 测试用例编号 | TC001 |
| 测试用例名称 | BSM → RMS 本地唤醒转换测试 |
| 测试目的 | 验证ECU从总线睡眠模式被本地唤醒后正确进入重复报文状态 |
| 预置条件 | • ECU处于Bus Sleep Mode • 总线完全静默 • 静态电流符合睡眠状态要求 |
| 测试步骤 | 1. 模拟KL15上电或其它本地唤醒事件 2. 测量从唤醒事件到首帧NM报文的时间 3. 验证首帧NM报文的控制位向量(Active Wakeup=1, Repeat Message Request=1) 4. 确认ECU进入Repeat Message State 5. 验证NM报文按配置周期稳定发送 |
| 预期结果 | • 唤醒响应时间 < 100ms • NM报文控制位正确设置 • ECU稳定保持在Repeat Message State |
| 验收标准 | 唤醒成功率100%,状态转换符合时序要求 |
/*----------------------------------------------------------------*/
/* 测试用例:TC001_BSM_to_RMS_Local_Wakeup_CAPL2010.can */
/* 测试目的:验证ECU从总线睡眠模式被本地唤醒后正确进入重复报文状态 */
/* 适用标准:AUTOSAR NM 4.3 */
/* 开发环境:CANoe 15.0 SP1 */
/* 作者:优快云 @车端域控测试工程师 */
/* 创建日期:2025-11-19 */
/*--------------------------------------------------------------*/
variables
{
// 网络管理相关常量定义
const long kNM_Message_ID = 0x500; // NM报文ID(根据实际项目配置)
const byte kCBV_ActiveWakeup = 0x80; // 控制位向量:主动唤醒位(bit7)
const byte kCBV_RepeatMessage = 0x01; // 控制位向量:重复报文请求位(bit0)
const int kExpected_Wakeup_Time = 100; // 预期唤醒响应时间(ms)
const int kNM_Message_Cycle = 1000; // NM报文周期(ms)
const float kCycle_Tolerance = 0.1; // 周期容忍度(10%)
// 测试控制变量
msTimer gWakeupEventTimer; // 唤醒事件定时器
msTimer gResponseTimeoutTimer; // 响应超时定时器
msTimer gNMStabilityTimer; // NM稳定性监控定时器
float gWakeupStartTime = 0; // 唤醒开始时间
float gFirstNMArrivalTime = 0; // 首帧NM报文到达时间
int gWakeupResponseTime = 0; // 唤醒响应时间
int gNM_Message_Count = 0; // NM报文计数
float gLastNM_Time = 0; // 上一帧NM报文时间
float gNM_Cycle_Sum = 0; // NM周期累计值
float gNM_Cycle_Avg = 0; // NM周期平均值
int gTestStep = 0; // 测试步骤控制
int gTestResult = -1; // 测试结果:-1=未执行,0=失败,1=通过
// 测试结果详细记录
struct TestResultRecord
{
int wakeupSuccess; // 唤醒成功标志
int responseTime; // 响应时间(ms)
byte firstCBV; // 首帧CBV值
int nmStability; // NM稳定性标志
char details[200]; // 详细描述
} gTestRecord;
}
/*----------------------------------------------------------------*/
/* 测试用例主函数:TC001_BSM_to_RMS_Local_Wakeup */
/* 功能:执行BSM到RMS的本地唤醒转换测试 */
/*--------------------------------------------------------------*/
testCase TC001_BSM_to_RMS_Local_Wakeup()
{
write("========== TC001 BSM → RMS 本地唤醒转换测试开始 ==========");
// 步骤0:测试环境准备和预置条件验证
testStepBegin("步骤0 - 测试环境准备和预置条件验证");
// 初始化测试变量
gTestStep = 0;
gTestResult = -1;
gNM_Message_Count = 0;
gNM_Cycle_Sum = 0;
gNM_Cycle_Avg = 0;
memset(gTestRecord, 0, elCount(gTestRecord));
// 验证预置条件1:ECU处于Bus Sleep Mode
write("验证预置条件:ECU处于Bus Sleep Mode");
// 方法:监控总线静默状态
setTimer(gResponseTimeoutTimer, 3000); // 监控3秒总线活动
gTestStep = 1; // 进入总线静默验证阶段
// 启动总线监控,确认无NM报文和其他应用报文
write("启动总线静默监控,持续3秒...");
}
/*----------------------------------------------------------------*/
/* 总线静默验证定时器处理函数 */
/* 功能:验证总线是否真正处于静默状态 */
/*--------------------------------------------------------------*/
on timer gResponseTimeoutTimer
{
if (gTestStep == 1) {
// 总线静默验证完成
testStepPass("总线静默验证通过 - ECU处于Bus Sleep Mode");
// 步骤1:模拟本地唤醒事件
testStepBegin("步骤1 - 模拟KL15本地唤醒事件");
// 记录唤醒开始时间
gWakeupStartTime = timeNow() / 100000.0; // 转换为毫秒精度
// 模拟KL15上电事件
// 注意:这里需要根据实际硬件接口选择唤醒方式
// 方式1:通过环境变量模拟KL15信号
setEnvironmentVariable("KL15_Status", 1);
// 方式2:通过CAN报文模拟唤醒信号(如果ECU支持)
// message 0x100 wakeupMsg;
// wakeupMsg.byte(0) = 0x01; // 唤醒命令
// output(wakeupMsg);
write("已发送KL15唤醒信号,等待ECU响应...");
write("唤醒开始时间: %.2f ms", gWakeupStartTime);
// 设置响应超时监控
setTimer(gResponseTimeoutTimer, 150); // 150ms响应超时
gTestStep = 2; // 进入响应等待阶段
}
else if (gTestStep == 2) {
// 响应超时处理
testStepFail("ECU未在150ms内响应唤醒事件");
gTestResult = 0;
generateTestReport();
testCaseFail("TC001测试失败 - ECU唤醒响应超时");
}
}
/*----------------------------------------------------------------*/
/* NM报文接收处理函数 */
/* 功能:处理接收到的NM报文,验证唤醒响应 */
/*--------------------------------------------------------------*/
on message kNM_Message_ID
{
float currentTime;
byte controlBitVector;
// 获取当前时间和控制位向量
currentTime = timeNow() / 100000.0; // 转换为毫秒精度
controlBitVector = this.byte(0); // 控制位向量在第一个字节
// 步骤2:首帧NM报文处理(唤醒响应)
if (gTestStep == 2) {
cancelTimer(gResponseTimeoutTimer); // 取消响应超时定时器
// 记录首帧NM报文到达时间
gFirstNMArrivalTime = currentTime;
gWakeupResponseTime = gFirstNMArrivalTime - gWakeupStartTime;
write("收到首帧NM报文!");
write("唤醒响应时间: %d ms", gWakeupResponseTime);
write("控制位向量(CBV): 0x%02X", controlBitVector);
// 验证响应时间
testStepBegin("步骤2 - 验证唤醒响应时间");
if (gWakeupResponseTime <= kExpected_Wakeup_Time) {
testStepPass("唤醒响应时间验证通过: %d ms ≤ %d ms",
gWakeupResponseTime, kExpected_Wakeup_Time);
gTestRecord.wakeupSuccess = 1;
gTestRecord.responseTime = gWakeupResponseTime;
} else {
testStepFail("唤醒响应时间超出预期: %d ms > %d ms",
gWakeupResponseTime, kExpected_Wakeup_Time);
gTestRecord.wakeupSuccess = 0;
}
// 验证控制位向量
testStepBegin("步骤3 - 验证首帧NM报文控制位向量");
int cbvCheckResult = 1;
char cbvDetails[100];
// 检查Active Wakeup位(bit7)
if ((controlBitVector & kCBV_ActiveWakeup) != 0) {
write(" ✓ Active Wakeup位 = 1 (本地唤醒)");
} else {
write(" ✗ Active Wakeup位 = 0 (应为1)");
cbvCheckResult = 0;
}
// 检查Repeat Message Request位(bit0)
if ((controlBitVector & kCBV_RepeatMessage) != 0) {
write(" ✓ Repeat Message Request位 = 1 (RMS状态)");
} else {
write(" ✗ Repeat Message Request位 = 0 (应为1)");
cbvCheckResult = 0;
}
if (cbvCheckResult) {
testStepPass("控制位向量验证通过");
gTestRecord.firstCBV = controlBitVector;
} else {
testStepFail("控制位向量验证失败");
}
// 记录首帧报文详细信息
snprintf(gTestRecord.details, elCount(gTestRecord.details),
"首帧NM报文: 时间=%.2fms, CBV=0x%02X, 响应时间=%dms",
gFirstNMArrivalTime, controlBitVector, gWakeupResponseTime);
// 步骤4:启动NM稳定性监控
testStepBegin("步骤4 - 验证ECU稳定保持在Repeat Message State");
gLastNM_Time = currentTime;
gNM_Message_Count = 1; // 首帧已计数
// 启动稳定性监控定时器(监控5个NM周期)
setTimer(gNMStabilityTimer, kNM_Message_Cycle * 5 * (1 + kCycle_Tolerance));
gTestStep = 3; // 进入稳定性监控阶段
write("启动NM稳定性监控,持续%d个周期...", 5);
}
// 步骤3:NM报文稳定性监控
else if (gTestStep == 3) {
float cycleTime;
// 计算当前NM报文周期
cycleTime = currentTime - gLastNM_Time;
gNM_Cycle_Sum += cycleTime;
gNM_Message_Count++;
// 更新上一帧时间
gLastNM_Time = currentTime;
// 实时显示NM报文统计信息(每5帧显示一次)
if ((gNM_Message_Count % 5) == 0) {
gNM_Cycle_Avg = gNM_Cycle_Sum / (gNM_Message_Count - 1);
write("NM报文统计: 计数=%d, 平均周期=%.2fms",
gNM_Message_Count, gNM_Cycle_Avg);
}
// 检查当前NM报文控制位向量是否保持RMS特征
if ((controlBitVector & kCBV_RepeatMessage) == 0) {
write("警告: NM报文Repeat Message Request位清零,可能已离开RMS状态");
}
}
}
/*----------------------------------------------------------------*/
/* NM稳定性监控定时器处理函数 */
/* 功能:处理NM稳定性监控超时,进行最终评估 */
/*--------------------------------------------------------------*/
on timer gNMStabilityTimer
{
if (gTestStep == 3) {
// 计算最终的平均周期
if (gNM_Message_Count > 1) {
gNM_Cycle_Avg = gNM_Cycle_Sum / (gNM_Message_Count - 1);
}
write("NM稳定性监控完成");
write("NM报文统计结果:");
write(" - 总报文数量: %d 帧", gNM_Message_Count);
write(" - 平均发送周期: %.2f ms", gNM_Cycle_Avg);
write(" - 预期发送周期: %d ms", kNM_Message_Cycle);
// 验证NM报文周期稳定性
testStepBegin("步骤5 - 验证NM报文周期稳定性");
float cycleError = abs(gNM_Cycle_Avg - kNM_Message_Cycle) / kNM_Message_Cycle;
if (cycleError <= kCycle_Tolerance) {
testStepPass("NM报文周期稳定性验证通过");
write("周期误差: %.2f%% ≤ %.1f%%", cycleError * 100, kCycle_Tolerance * 100);
gTestRecord.nmStability = 1;
} else {
testStepFail("NM报文周期稳定性验证失败");
write("周期误差: %.2f%% > %.1f%%", cycleError * 100, kCycle_Tolerance * 100);
gTestRecord.nmStability = 0;
}
// 步骤6:综合测试结果评估
testStepBegin("步骤6 - 综合测试结果评估");
int overallResult = 1;
char resultDetails[500];
snprintf(resultDetails, elCount(resultDetails),
"TC001测试结果详情:\n"
"1. 唤醒成功: %s\n"
"2. 响应时间: %d ms (%s)\n"
"3. 控制位向量: 0x%02X (%s)\n"
"4. NM稳定性: %s\n",
gTestRecord.wakeupSuccess ? "✓ 通过" : "✗ 失败",
gTestRecord.responseTime,
gTestRecord.responseTime <= kExpected_Wakeup_Time ? "符合" : "超时",
gTestRecord.firstCBV,
(gTestRecord.firstCBV & (kCBV_ActiveWakeup | kCBV_RepeatMessage)) ==
(kCBV_ActiveWakeup | kCBV_RepeatMessage) ? "正确" : "错误",
gTestRecord.nmStability ? "✓ 稳定" : "✗ 不稳定");
write(resultDetails);
// 检查所有验收标准
if (gTestRecord.wakeupSuccess &&
gTestRecord.responseTime <= kExpected_Wakeup_Time &&
(gTestRecord.firstCBV & (kCBV_ActiveWakeup | kCBV_RepeatMessage)) ==
(kCBV_ActiveWakeup | kCBV_RepeatMessage) &&
gTestRecord.nmStability) {
gTestResult = 1;
testCasePass("TC001测试通过 - BSM→RMS本地唤醒转换完全符合要求");
snprintf(gTestRecord.details, elCount(gTestRecord.details),
"测试通过: 唤醒成功率100%%, 响应时间%dm符合要求, 状态转换时序正确",
gTestRecord.responseTime);
} else {
gTestResult = 0;
testCaseFail("TC001测试失败 - 部分验收标准未满足");
// 生成详细的失败原因
char failReason[300];
snprintf(failReason, elCount(failReason),
"失败原因: 唤醒成功=%d, 响应时间=%dms, CBV正确=%d, NM稳定=%d",
gTestRecord.wakeupSuccess,
gTestRecord.responseTime,
((gTestRecord.firstCBV & (kCBV_ActiveWakeup | kCBV_RepeatMessage)) ==
(kCBV_ActiveWakeup | kCBV_RepeatMessage)),
gTestRecord.nmStability);
strcat(gTestRecord.details, failReason);
}
// 生成最终测试报告
generateTestReport();
}
}
/*----------------------------------------------------------------*/
/* 测试报告生成函数 */
/* 功能:生成详细的测试报告 */
/*--------------------------------------------------------------*/
void generateTestReport()
{
write("========== TC001 测试报告 ==========");
write("测试用例: BSM → RMS 本地唤醒转换测试");
write("测试结果: %s", (gTestResult == 1) ? "通过" :
(gTestResult == 0) ? "失败" : "未完成");
write("执行时间: %s", getTimestamp());
write("------------------------------------");
write("详细结果:");
write(" 唤醒成功: %s", gTestRecord.wakeupSuccess ? "是" : "否");
write(" 响应时间: %d ms", gTestRecord.responseTime);
write(" 首帧CBV: 0x%02X", gTestRecord.firstCBV);
write(" NM稳定性: %s", gTestRecord.nmStability ? "稳定" : "不稳定");
write(" NM报文数量: %d", gNM_Message_Count);
write(" NM平均周期: %.2f ms", gNM_Cycle_Avg);
write("------------------------------------");
write("详细信息:");
write(" %s", gTestRecord.details);
write("====================================");
}
/*----------------------------------------------------------------*/
/* 时间戳获取辅助函数 */
/* 功能:获取格式化的时间戳 */
/*--------------------------------------------------------------*/
char* getTimestamp()
{
static char timestamp[50];
long systemTime;
systemTime = timeNow() / 10000; // 转换为0.1ms单位
snprintf(timestamp, elCount(timestamp),
"%02d:%02d:%02d.%03d",
(systemTime / 3600000) % 24, // 小时
(systemTime / 60000) % 60, // 分钟
(systemTime / 1000) % 60, // 秒
systemTime % 1000); // 毫秒
return timestamp;
}
/*----------------------------------------------------------------*/
/* 环境变量变化处理函数 */
/* 功能:监控KL15状态变化(如果使用环境变量方式) */
/*--------------------------------------------------------------*/
on envVar KL15_Status
{
write("KL15状态变化: %d", this);
// 如果KL15被意外关闭,记录警告
if (this == 0 && (gTestStep == 2 || gTestStep == 3)) {
write("警告: 测试过程中KL15被意外关闭!");
}
}
/*----------------------------------------------------------------*/
/* 其他总线活动监控函数 */
/* 功能:监控非NM报文的总线活动 */
/*--------------------------------------------------------------*/
on message *
{
// 在总线静默验证阶段,监控到任何报文都表示未完全进入睡眠
if (gTestStep == 1 && this.id != kNM_Message_ID) {
write("检测到非NM报文: ID=0x%03X, 总线未完全静默", this.id);
}
}
/*----------------------------------------------------------------*/
/* 测试用例初始化函数 */
/* 功能:在测试开始前执行的环境初始化 */
/*--------------------------------------------------------------*/
on start
{
write("TC001测试环境初始化完成");
write("配置参数:");
write(" NM报文ID: 0x%03X", kNM_Message_ID);
write(" 预期唤醒时间: %d ms", kExpected_Wakeup_Time);
write(" NM报文周期: %d ms", kNM_Message_Cycle);
write(" 周期容忍度: %.1f%%", kCycle_Tolerance * 100);
}
/*----------------------------------------------------------------*/
/* 测试用例清理函数 */
/* 功能:在测试结束时清理环境 */
/*--------------------------------------------------------------*/
on stop
{
// 取消所有定时器
cancelTimer(gWakeupEventTimer);
cancelTimer(gResponseTimeoutTimer);
cancelTimer(gNMStabilityTimer);
// 恢复KL15状态(如果测试中修改了)
setEnvironmentVariable("KL15_Status", 0);
write("TC001测试环境清理完成");
}
/*----------------------------------------------------------------*/
/* 错误处理函数 */
/* 功能:处理测试过程中的异常情况 */
/*--------------------------------------------------------------*/
on error
{
write("测试执行错误: %s", this.ToString());
gTestResult = 0;
generateTestReport();
testCaseFail("TC001测试执行过程中发生错误");
}
/*----------------------------------------------------------------*/
/* 测试用例调试信息函数 */
/* 功能:提供测试状态查询接口 */
/*----------------------------------------------------------------*/
void getTC001_Status()
{
write("=== TC001 当前状态 ===");
write("测试步骤: %d", gTestStep);
write("测试结果: %d", gTestResult);
write("NM报文计数: %d", gNM_Message_Count);
write("响应时间: %d ms", gWakeupResponseTime);
write("最后活动: %s", getTimestamp());
write("=====================");
}
代码详细说明
1. 测试架构设计
本CAPL测试代码采用分层状态机设计,通过gTestStep变量精确控制测试流程:
- 步骤0: 环境准备和预置条件验证
- 步骤1: 模拟本地唤醒事件
- 步骤2: 验证唤醒响应时间和首帧NM报文
- 步骤3: NM稳定性监控和周期验证
- 步骤4: 综合结果评估和报告生成
2. 关键功能模块
2.1 总线静默验证
// 通过监控3秒内总线活动,确保ECU真正进入Bus Sleep Mode
setTimer(gResponseTimeoutTimer, 3000);
2.2 本地唤醒模拟
// 两种唤醒方式支持:
// 1. 环境变量方式(适用于虚拟ECU或硬件在环)
setEnvironmentVariable("KL15_Status", 1);
// 2. CAN报文方式(适用于真实ECU测试)
// message 0x100 wakeupMsg;
// output(wakeupMsg);
2.3 响应时间精确测量
// 使用高精度时间测量
gWakeupStartTime = timeNow() / 100000.0;
gFirstNMArrivalTime = timeNow() / 100000.0;
gWakeupResponseTime = gFirstNMArrivalTime - gWakeupStartTime;
2.4 控制位向量验证
// 验证Active Wakeup位和Repeat Message Request位
if ((controlBitVector & kCBV_ActiveWakeup) != 0) {
// 本地唤醒验证通过
}
if ((controlBitVector & kCBV_RepeatMessage) != 0) {
// RMS状态验证通过
}
2.5 NM稳定性分析
// 计算平均周期和稳定性
gNM_Cycle_Avg = gNM_Cycle_Sum / (gNM_Message_Count - 1);
float cycleError = abs(gNM_Cycle_Avg - kNM_Message_Cycle) / kNM_Message_Cycle;
3. 测试覆盖率保障
本测试用例确保100%覆盖TC001的所有验证要点:
- ✅ 唤醒响应时间:精确测量并验证<100ms要求
- ✅ 控制位向量:全面检查Active Wakeup和Repeat Message Request位
- ✅ 状态确认:通过NM报文特征确认ECU进入Repeat Message State
- ✅ 稳定性验证:长期监控NM报文周期稳定性
- ✅ 边界条件:包含超时处理和异常情况监控
4. 实际应用建议
- 参数配置:根据实际项目修改
kNM_Message_ID、kNM_Message_Cycle等常量 - 唤醒方式:选择适合目标ECU的唤醒模拟方式
- 环境适配:调整定时器超时时间适应不同ECU的响应特性
- 扩展功能:可根据需要添加更多诊断信息和性能统计
5. 预期测试输出
执行成功的测试将输出如下信息:
========== TC001 测试报告 ==========
测试用例: BSM → RMS 本地唤醒转换测试
测试结果: 通过
执行时间: 14:30:25.123
------------------------------------
详细结果:
唤醒成功: 是
响应时间: 45 ms
首帧CBV: 0x81
NM稳定性: 稳定
NM报文数量: 15
NM平均周期: 998.5 ms
------------------------------------
详细信息:
首帧NM报文: 时间=1450.25ms, CBV=0x81, 响应时间=45ms
====================================
该CAPL代码提供了完整、鲁棒的测试实现,可直接用于AUTOSAR网络管理相关项目的验证工作。
AUTOSAR网络管理测试实现
1576

被折叠的 条评论
为什么被折叠?



