CANoe 使用指南:从输出窗口到数据回放的完整实战教程

目录

前言

一、输出窗口

[1. 新建页面](#1. 新建页面)

[2. 输出函数汇总](#2. 输出函数汇总)

[1. write](#1. write)

[2. writeLineEx](#2. writeLineEx)

[3. writeEx](#3. writeEx)

[4. writeConfigure](#4. writeConfigure)

[5. writeDbgLevel](#5. writeDbgLevel)

二、仿真设置

[1. 配置总线的网络属性](#1. 配置总线的网络属性)

[2. 激活/禁用节点](#2. 激活/禁用节点)

[3. 网络重命名](#3. 网络重命名)

[4. 节点DLL配置](#4. 节点DLL配置)

三、分析窗口

[1. Trace 窗口](#1. Trace 窗口)

[1. 预定义过滤](#1. 预定义过滤)

[2. 分析过滤](#2. 分析过滤)

[3. 激活禁用过滤](#3. 激活禁用过滤)

[2. 统计窗口](#2. 统计窗口)

[1. 统计窗口的系统变量](#1. 统计窗口的系统变量)

[2. 统计窗口的 CAPL 函数](#2. 统计窗口的 CAPL 函数)

[3. Graphics 窗口](#3. Graphics 窗口)

四、日志模块

[1. 日志模块的配置](#1. 日志模块的配置)

[2. CAPL 内置函数](#2. CAPL 内置函数)

五、数据回放

[1. 分析窗口回放和离线回放](#1. 分析窗口回放和离线回放)

[1. 分析窗口回放](#1. 分析窗口回放)

[2. 离线回放](#2. 离线回放)

[2. 在线回放](#2. 在线回放)

[1. 回放模块配置](#1. 回放模块配置)

[2. 节点过滤](#2. 节点过滤)

[3. CAPL 控制回放](#3. CAPL 控制回放)

总结


前言

CANoe 是 Vector 公司推出的一款专业总线开发与测试工具,广泛应用于汽车电子领域的网络仿真、报文分析、节点调试和自动化测试。无论是 CAN、LIN 还是 FlexRay 总线,CANoe 都提供了从工程搭建、仿真运行到数据回放的一整套解决方案,是车载网络开发与测试工程师日常工作中不可或缺的工具之一。

本文围绕 CANoe 的常用功能模块展开,重点介绍输出窗口、仿真设置、分析窗口、日志模块以及数据回放这几个核心部分,并结合 CAPL 脚本给出可运行的示例代码,帮助读者快速上手并理解各模块的实际用途。

文章内容主要分为以下几个部分:

  • 输出窗口:介绍 Write 窗口的页面管理、常用输出函数及调试信息的分级控制;
  • 仿真设置:讲解网络属性配置、节点激活与禁用、网络重命名以及节点 DLL 配置;
  • 分析窗口:涵盖 Trace、统计窗口和 Graphics 窗口的过滤、统计与截图功能;
  • 日志模块:说明如何使用 CAPL 触发日志采集并保存测试数据;
  • 数据回放:介绍分析窗口回放、离线回放和在线回放的使用方法。

希望通过本文的介绍,读者能够对 CANoe 的常用功能有一个整体认识,并在实际项目中灵活运用这些工具模块,提高开发与测试效率。


一、输出窗口

输出窗口就是 Write 窗口,主要的作用是调试;

Write 窗口默认是有 4 个页面:

  • Overview:所有类型的信息都输出在此页面;
  • System:用于显示系统消息;
  • Program/Model:显示脚本(CAPL,.NET,Python)中的输出消息;
  • Test:显示测试函数库(Test Feature Set,Test Service Library)中的输出消息;

1. 新建页面

Write 窗口还支持新建页面,常用函数如下:

dword writeCreate(char name\[\]):创建一个新的页面,传入页面名称,返回页面句柄;

void writeConfigure(dword sink, dword lines, dword logging, char filename\[\]):配置页面的行数,是否保存日志,及文件名称;

void writeClear(dword sink):清空页面消息;

void writeLineEx(long sink, dword severity, char format\[\], ...):在页面输出级别为 severity 级别的消息,消息可使用格式化字符串;

void writeDestory(dword sink):删除自定义的页面;

cpp 复制代码
variables
{
  long newPage;
}

on start
{
  newPage = writeCreate("New Page"); // 创建页面
  writeConfigure(newPage, 20, 1, "WriteLog.txt"); // 配置日志保存路径
  writeClear(newPage); // 清空页面信息
  writeLineEx(newPage, 1, "create Write window sub page: New Page"); // 在创建的页面上输出内容
}

on key 'a'
{
  writeLineEx(newPage, 1, "pressed key %c", this);
}

on stopMeasurement
{
  writeDestroy(newPage); // 销毁页面
}

2. 输出函数汇总

1. write

void write(char format\[\], ...):最基本的格式化输出信息的函数;

2. writeLineEx

void writeLineEx(long sink, dword severity, char format\[\], ...):在指定页面或者 Trace 窗口,输出指定类型的信息;

sink:

  • -4:输出到 Trace 窗口和 Logging 文件;
  • -3:输出到 Trace 窗口;
  • -2:输出到 logging file;
  • -1:Reserved;
  • 0:输出到 Write 窗口 System 子页面;
  • 1:输出到 Write 窗口 CAPL 子页面;
  • 4:输出到 Write 窗口 Test 子页面;

severity:

  • 0:Success
  • 1:Information
  • 2:Warning
  • 3:Error

示例代码:

cpp 复制代码
variables
{
  long newPage;
  
  enum Sink
  {
    TRACE_LOG = -4,
    TRACE,
    LOG,
    SYSTEM_PAGE = 0,
    CAPL_PAGE,
    TEST_PAGE
  };
  enum Severity
  {
    SUCCESS,
    INFORMATION,
    WARNING,
    ERROR
  };
}

on key 'b'
{
  writeLineEx(SYSTEM_PAGE, SUCCESS, "pressed key %c", this);
  
  writeLineEx(SYSTEM_PAGE, SUCCESS, "success message");
  writeLineEx(SYSTEM_PAGE, INFORMATION, "info message");
  writeLineEx(SYSTEM_PAGE, WARNING, "warning message");
  writeLineEx(SYSTEM_PAGE, ERROR, "error message");
}
cpp 复制代码
on key 'c'
{
  writeLineEx(TRACE, SUCCESS, "pressed key %c", this);
  
  writeLineEx(TRACE, SUCCESS, "success message");
  writeLineEx(TRACE, INFORMATION, "info message");
  writeLineEx(TRACE, WARNING, "warning message");
  writeLineEx(TRACE, ERROR, "error message");
}

3. writeEx

void writeEx(long sink, dword severity, char format\[\], ...):和 writeLineEx 函数功能类似,唯一区别是不换行打印。

cpp 复制代码
on key 'd'
{
  writeEx(SYSTEM_PAGE, SUCCESS, "pressed key %c", this);
  
  writeEx(SYSTEM_PAGE, SUCCESS, "success message");
  writeEx(SYSTEM_PAGE, INFORMATION, "info message");
  writeEx(SYSTEM_PAGE, WARNING, "warning message");
  writeEx(SYSTEM_PAGE, ERROR, "error message");
}

4. writeConfigure

void writeConfigure(dword sink, dword lines, dword logging, char filename\[\]):用于将 Write 窗口指定子页面的信息保存到文件中;

filename 如果不存在会自动创建,如果路径不存在,无法自动创建;

logging 参数设置为 1 表示保存 log,测试完成后要设置为 0;

文件记录的方式是向后追加;

cpp 复制代码
variables
{
  long newPage;
  
  enum Sink
  {
    TRACE_LOG = -4,
    TRACE,
    LOG,
    SYSTEM_PAGE = 0,
    CAPL_PAGE,
    TEST_PAGE
  };
  enum Severity
  {
    SUCCESS,
    INFORMATION,
    WARNING,
    ERROR
  };
  
  enum SaveFlag
  {
    SAVE,
    UNSAVE
  };
}

on key 'e'
{
  writeLineEx(SYSTEM_PAGE, SUCCESS, "pressed key %c", this);
  
  writeConfigure(SYSTEM_PAGE, 200, SAVE, "WriteLog.txt");
  
  writeLineEx(TRACE, SUCCESS, "success message");
  writeLineEx(TRACE, INFORMATION, "info message");
  writeLineEx(TRACE, WARNING, "warning message");
  writeLineEx(TRACE, ERROR, "error message");
  
  writeConfigure(SYSTEM_PAGE, 200, UNSAVE, "WriteLog.txt");
}

5. writeDbgLevel

void setWriteDbgLevel(unsigned int priority):设置优先级;

long writeDbgLevel(unsigned int priority, char format1\[\], char format2\[\], ...):和上面的函数配合使用,先设置优先级,再输出调试信息;

  • 如果 writeDbgLevel() 的优先级小于等于 setWriteDbgLevel() 设置的优先级,则输出调试信息,否则不输出调试信息;
  • priority 参数值越小,优先级越高,0 为最高优先级,15为最低优先级;
cpp 复制代码
on key 'f'
{
  setWriteDbgLevel(7);
  
  writeDbgLevel(4, "4 < 7, this message will be output");
  writeDbgLevel(8, "8 > 7, this message will not be output");
  
  setWriteDbgLevel(8);
  writeDbgLevel(8, "8 = 8, this message will be output");
}

二、仿真设置

仿真设置窗口用于配置和管理 CANoe 仿真环境的对象,可以进行网络配置和节点配置;

在 Simulation Setup 窗口右键,选择 System View 之后,可以调出 Networks 窗口:

1. 配置总线的网络属性

CAN 总线只有连接了干扰仪(VH6501)之后,才需要勾选 Active:

CAN 网络干扰仪配置:

如果是真实的总线,没有连接 ECU,CANoe 发送报文会报 NoACK 的错误帧,如果用户勾选 TX Self-ACK,即使没有真实节点响应,仿真节点也会自己响应 ACK 应答,没有错误帧:

2. 激活/禁用节点

在节点上右键,选择 Block Active 可以激活节点,不选择可以禁用节点:

除了通过图形界面手动操作之外,CAPL 内置函数也可以实现启动/禁用节点,这样可以在测试脚本中根据运行状态动态控制节点的在线与离线,从而模拟真实总线中节点掉线或恢复的场景。

network node:

  • canOffline():禁用节点,使该网络节点停止参与总线通信,不再发送或接收报文;
  • canOnline():启用节点,使该网络节点恢复在线状态,重新参与总线通信;

这两个函数通常成对使用,用于在测试过程中模拟节点掉线、恢复等异常场景,验证被测系统在节点缺失或恢复时的行为是否符合预期。

test node:

testSetEcuOffline():将测试节点设置为离线状态,使其不再执行测试逻辑;

testSetEcuOnline():将测试节点恢复为在线状态,使其继续执行测试逻辑;

与 network node 的 canOffline/canOnline 类似,test node 的这两个函数用于在测试运行过程中动态控制测试节点的启停,常用于需要分阶段执行测试用例的场景,例如先让测试节点离线以跳过某段测试,再恢复在线继续后续测试。

3. 网络重命名

在网络右键,选择 Rename 可以对网络进行重命名:

在 CANoe 仿真工程中,一般存在多个网络拓扑。用户使用 CAPL 函数对网络中的节点,报文,信号等元素进行操作时,如果元素符号存在多条网络中,就需要先通过 setBusContext() 函数设置总线环境,才能对该网络下的元素进行操作;

dword getBusNameContext(char name\[\]):查询总线是否存在,如果不存在,返回 0,存在返回非零整数(context 对象的句柄);

dword setBusContext(dword context):设置总线环境,输入的值是 getBusNameContext() 的返回值(context 对象的句柄);

cpp 复制代码
on key '4'
{
  long context;
  
  context = getBusNameContext("CAN");
  
  if(context != 0)
  {
    setBusContext(context);
    
    testDisableMsg("EngineState");
    testWaitForTimeout(2000);
    testEnableMsg("EngineState");
  }
}

4. 节点DLL配置

进行网络节点配置时,在 Components 页面可以引用不同的 DLL 文件;

CAN 总线必须加载 CANOEILVECTOR.DLL,仿真节点才会按照数据库中定义的方式进行发送报文;

三、分析窗口

CANoe 可以在 Measurement Setup 窗口中添加各种类型的分析窗口,如 Trace,Data,Graphics 等,还可以使用 Logging 模块保存测试数据;

1. Trace 窗口

1. 预定义过滤

预定义过滤可以设置过滤条件,根据消息类型进行筛选,比如 CAN 报文,系统变量等;

可以设置不同的选项过滤消息:

  • 不缓存消息,也不显示消息;
  • 缓存在 Trace 缓冲区,但不在 Trace 窗口显示;
  • 保存在 Trace 缓冲区,也在 Trace 窗口中显示;

2. 分析过滤

分析过滤是自定义分析过滤器,分为 Pass Filter 和 Stop Filter;

分析过滤器只影响 Trace 窗口中显示的视图,不会从数据流中删除事件;

3. 激活禁用过滤

用户可以通过 Active/Deactive Analysis Filters 激活/禁用分析过滤;

用户可以通过 Active/Deactive Analysis Column Filters 功能来激活或禁用表头的筛选;

2. 统计窗口

统计窗口用于统计总线负载,报文数量,错误计数等;

1. 统计窗口的系统变量

CANoe 工程插入 Statistics 模块后,会在系统变量 System Defined 中自动生成以 _Statistics 命名空间的系统变量:

上述系统变量无法在网络节点和测试节点中使用,只能在编程节点中访问,访问方式如下:

2. 统计窗口的 CAPL 函数

总线负载率和错误帧数是 CAN 网络的重要指标参数,CAN 要求 ECU 在高负载下具有稳定性;

long busload():获取总线负载率;

long ErrorFrameCount():获取总线错误帧数;

cpp 复制代码
on key 'a'
{
  long busload;
  long errorFrameCount;
  
  busload = CAN1.BusLoad;
  write("CAN1 busload: %ld%%",  busload);
  
  output(errorFrame);
  output(errorFrame);
  
  errorFrameCount = CAN1.ErrorFrameCount;
  write("CAN1 error frame count: %ld", errorFrameCount);
}

3. Graphics 窗口

重点介绍一些 Graphics 窗口的截图功能;

在 Graphics 的空白区域点击右键,选择 Copy Screenshot,可以将当前窗口进行截图;

在 CAPL 中使用 TestReportAddWindowCapture(),可以将窗口截图添加到测试报告中:

cpp 复制代码
testcase TC_001()
{
  testWaitForTimeout(2000);
  TestReportAddWindowCapture("Graphics", "", "Screenshot of Graphics window");
}

void MainTest()
{
  TC_001();
}

四、日志模块

主要讲解如何使用 CAPL 记录日志;

1. 日志模块的配置

首先要选择 Toggle trigger:

选择 Toggle 模式之后,Toggle on 和 Toggle off 都要选择 CAPL,表示使用 CAPL 进行触发数据的采集和停止;

并且设置 Pre-trigger time:表示触发前采集多少时间的数据;

设置 Post-trigger time:表示出发后采集多长时间的数据;

因为在实际测试中,如果不设置 Pre-trigger time 和 Post-trigger time,采集到的数据有可能不完整,出现问题,不便于分析,因此触发前后,都多采集一段时间,保证数据完整;

2. CAPL 内置函数

void startLogging():开始启动所有报文采集模块;

void startLogging(char strLoggingBlockName\[\]):启动名为 strLoggingBlockName 的 Logging 模块;

void startLogging(char strLoggingBlockName\[\], long preTriggerTime):启动一个名为 strLoggingBlockName 的 Logging 模块,同时保存前 preTriggerTime 的时间的数据;

void stopLogging():停止所有的 Logging 模块;

void stopLogging(char strLoggingBlockName\[\]):停止名为 strLoggingBlockName 的 Logging 模块;

void stopLogging(char strLoggingBlockName\[\], long postTriggerTime):停止一个名为 strLoggingBlockName 的 Logging 模块,同时保存后 postTriggerTime 的时间的数据;

cpp 复制代码
testcase TC_LoggingTest()
{
  testWaitForTimeout(2000);
  startLogging("Logging", 1000);
  testWaitForTimeout(10000);
  stopLogging("Logging", 1000);
  testWaitForTimeout(2000);
}

void setLogFileName(char fileName\[\]):设置日志文件名称;

void setLogFileName(char strLoggingBlockName\[\], char fileName\[\]):设置日志文件名称;

cpp 复制代码
testcase TC_LoggingTest_2()
{
  setLogFileName("Logging", "example");
  
  testWaitForTimeout(2000);
  startLogging("Logging", 1000);
  testWaitForTimeout(10000);
  stopLogging("Logging", 1000);
  testWaitForTimeout(2000);
}

五、数据回放

1. 分析窗口回放和离线回放

1. 分析窗口回放

直接将要会放的数据,拖动到 Trace 窗口即可;

2. 离线回放

在 Measurement Setup 窗口,切换到 Offline 模式,打开 Offline Mode 对话框,选择要回放的日志文件:

选择好文件之后,可以选择立即回放(start),或者按步骤回放(step);

2. 在线回放

在 Simulation Setup 窗口,选择 Insert Replay Block CAN,插入一个 Replay Block 模块:

1. 回放模块配置


2. 节点过滤

回放主要是为了进行分析或者仿真,进行数据分析可以直接使用前面的方法,如果要进行仿真,可以使用回放模块;

使用回放模块进行仿真,需要注意,一定要把要测试的目标 ECU 过滤掉,避免仿真的数据影响测试;

3. CAPL 控制回放

ReplayResume():重启回放;

ReplayStart():开始回放

ReplayState():返回 Replay 的状态;

ReplayStop():停止回放;

ReplaySuspend():暂停回放;

SetReplayFileName():设置回放文件;

cpp 复制代码
variables
{
  char replayName[30] = "ReplayBlock 1";
}

on key 'b'
{
  replayStart(replayName);
  writeReplayState(replayName);
}

on key 's'
{
  replaySuspend(replayName);
  writeReplayState(replayName);
}

on key 'r'
{
  replayResume(replayName);
  writeReplayState(replayName);
}

on key 'e'
{
  replayStop(replayName);
  writeReplayState(replayName);
}

void writeReplayState(char replayName[])
{
  switch(replayState(replayName))
  {
    case 0:
      write("%s is stopped", replayName);
      break;
    case 1:
      write("%s is running", replayName);
      break;
    case 2:
      write("%s is suspend", replayName);
      break;
    default:
      write("%s is error", replayName);
  }
}

总结

本文围绕 CANoe 的常用功能模块进行了系统梳理,从输出窗口、仿真设置、分析窗口、日志模块到数据回放,基本覆盖了车载网络开发与测试中常用的操作场景。

在输出窗口部分,我们了解了 Write 窗口的页面管理方式,以及 write、writeLineEx、writeEx、writeConfigure、writeDbgLevel 等常用输出函数的用法,掌握了如何通过 CAPL 灵活控制调试信息的输出位置、级别和日志保存。

在仿真设置部分,重点讲解了网络属性配置、节点激活与禁用、网络重命名以及节点 DLL 配置。通过 CAPL 内置函数可以动态控制节点的在线与离线,从而模拟真实总线中节点掉线或恢复的场景,为异常场景测试提供了便利。

在分析窗口部分,介绍了 Trace 窗口的预定义过滤、分析过滤和激活禁用过滤,统计窗口的系统变量与 CAPL 函数,以及 Graphics 窗口的截图功能。合理使用这些过滤和统计手段,可以更高效地定位和分析总线数据。

在日志模块部分,说明了如何通过 Toggle trigger 配合 Pre-trigger time 和 Post-trigger time 采集完整数据,并介绍了 startLogging、stopLogging、setLogFileName 等 CAPL 内置函数,帮助读者在测试过程中灵活控制日志的采集与保存。

在数据回放部分,介绍了分析窗口回放、离线回放和在线回放三种方式,并说明了回放模块的配置、节点过滤以及 CAPL 控制回放的方法。回放功能既可以用于数据分析,也可以用于仿真验证,是测试复现和问题定位的重要工具。

总的来说,CANoe 的各个功能模块相互配合,构成了从仿真搭建、数据采集、分析定位到回放验证的完整工作流。希望读者能够结合本文的示例代码,在实际项目中多加练习,逐步掌握这些工具的使用技巧,从而提升车载网络开发与测试的效率。

相关推荐
当青春邂逅吉米多维奇1 小时前
C#图解教程(第5版) 同步方法
开发语言·c#
龙腾-虎跃1 小时前
Practicum4ECE 项目深度解析:电子工程实践课程全攻略
自动化·毕业设计·电子信息·竞赛·电子工程
骇客野人1 小时前
Java BIO / NIO / AIO 完整详解 + 编程技巧
java·开发语言·nio
霸道流氓气质1 小时前
OpenTelemetry 入门与实战:Java Agent、Spring Boot Starter与LLM调用追踪示例
java·开发语言·spring boot
波力海苔夹心脆6751 小时前
C# 机器视觉实战:单相机引导机械手精准贴合,从拍照、偏差计算(平移+旋转)到坐标补偿全解
开发语言·经验分享·数码相机·c#·视觉检测·.net
外收内放2 小时前
Python基础语法练习题(62原始版本及其优化版本)
开发语言·python
马剑威(威哥爱编程)2 小时前
【AI全栈后端12-12】Spring Boot 3.x 到 4.x 迁移实操:Jakarta 11、Jackson 3 与 AI 2.0
java·开发语言·spring boot·后端
dghongcheng2 小时前
汽车零部件涂装方案:保险杠涂装线的技术要点
自动化·汽车·喷涂设备·喷涂·喷漆设备·自动喷涂线
luiyarch2 小时前
汽车电子ISO 21448 SOTIF系列(第26期):未知危险场景的确认方法(下)——AI驱动的场景发现
网络·人工智能·安全·车载系统·汽车