4. 基于事件触发的CAN消息发送

任务定义

在CANoe中,周期型发送的CAN消息无法满足“仅在特定条件发生时发送”的场景(如车门解锁、档位切换等)。本案例要求实现一个基于事件触发的CAN消息发送脚本:当检测到某个输入信号(例如点火状态从OFF变为ON)时,立即发送一条自定义CAN消息(例如0x123),且该消息仅在事件发生时发送一次,不进行周期发送。

实现方案

使用CAPL程序,通过系统变量或环境变量作为事件源。本案例采用系统变量作为触发源(便于手动仿真验证),在系统变量值变化时触发发送逻辑。核心思路:

  1. 在CANoe仿真节点中编写CAPL程序;
  2. 监控系统变量 SysVar::IgnitionState(整型,0=OFF,1=ON);
  3. 当变量值从0变为1时,调用 output() 函数发送CAN消息 0x123;
  4. 消息数据域填充当前时间戳(秒为单位)和事件计数器。

CAPL代码实现

/* 事件触发发送节点 - EventSender.can */
variables
{
  message 0x123 EventMsg = { dlc = 8 };
  int lastIgnitionState = 0;   // 记录上一次点火状态
  int eventCounter = 0;        // 事件计数器
}

on sysvar SysVar::IgnitionState
{
  int currentState = @this;
  
  // 检测上升沿:OFF(0) -> ON(1)
  if (currentState == 1 && lastIgnitionState == 0)
  {
    eventCounter++;
    EventMsg.byte(0) = eventCounter & 0xFF;          // 计数器低字节
    EventMsg.byte(1) = (eventCounter & 0xFF00) >> 8; // 计数器高字节
    EventMsg.byte(2) = timeNow() & 0xFF;             // 时间戳低字节
    EventMsg.byte(3) = (timeNow() >> 8) & 0xFF;      // 时间戳高字节
    EventMsg.byte(4) = 0xAA;                          // 固定标识
    EventMsg.byte(5) = 0x55;                          // 固定标识
    EventMsg.byte(6) = 0x00;                          // 保留
    EventMsg.byte(7) = 0x00;                          // 保留
    
    output(EventMsg);  // 发送消息
    write("事件触发: 0x123 已发送, 计数器=%d", eventCounter);
  }
  
  lastIgnitionState = currentState;
}

on start
{
  write("事件发送节点已启动,等待点火状态变化...");
}

工程配置与运行步骤

  1. 创建系统变量:在CANoe的Simulation Setup中,打开System Variables窗口,新建变量 IgnitionState(类型Integer,初始值0)。
  2. 添加CAPL节点:在Simulation Setup中添加一个Network Node,将上述代码粘贴到该节点的CAPL编辑器中。
  3. 配置CAN通道:确保该节点连接到CAN总线(如CAN 1),消息0x123的发送通道与节点所在通道一致。
  4. 启动测量:点击“Start Measurement”开始仿真。
  5. 触发事件:在System Variables窗口或使用Write窗口的 setSysVar(SysVar::IgnitionState, 1) 命令,将点火状态从0改为1。

验证方法与判定标准

验证步骤:

  1. 启动测量后,在Trace窗口添加CAN消息过滤,只显示ID=0x123的消息;
  2. 在Write窗口执行 setSysVar(SysVar::IgnitionState, 1);
  3. 观察Trace窗口是否出现一条0x123消息;
  4. 再次执行 setSysVar(SysVar::IgnitionState, 0),再执行 setSysVar(SysVar::IgnitionState, 1),观察是否出现第二条0x123消息。

判定标准:

  • 每次点火状态从0变为1时,Trace窗口恰好新增一条0x123消息;
  • 点火状态保持为1不变时,不产生新的0x123消息;
  • 消息数据域中:byte(0)和byte(1)组成的计数器值逐次递增1;byte(2)和byte(3)组成的时间戳与当前仿真时间一致(允许±1秒误差);byte(4)=0xAA,byte(5)=0x55。
事件触发CAN消息发送 - 验证拓扑与数据流 系统变量 SysVar::IgnitionState 0=OFF / 1=ON 上升沿检测 0→1 跳变 lastIgnitionState 发送消息 output(0x123) 计数器+时间戳 CAN 总线 0x123 消息帧结构 (DLC=8) Byte0 计数器L Byte1 计数器H Byte2 时间戳L Byte3 时间戳H Byte4 0xAA Byte5 0x55 Byte6 保留 Byte7 保留 观测点: Trace窗口过滤0x123

关键说明

  • 本实现仅响应系统变量IgnitionState的上升沿,不响应下降沿,也不进行周期发送;
  • 计数器eventCounter在每次事件触发时递增,用于验证事件确实发生;
  • 时间戳使用timeNow()函数获取仿真时间(单位秒),便于与Trace窗口时间对照;
  • 若需改为真实信号触发,只需将on sysvar替换为on message或on signal,并在相应事件中判断信号值变化即可。