CAPL 编程系列教程的第二十一期内容,继续讲解 CAPL 中的事件 (Events),本期重点是通过实例演示系统测量事件 (Measurement Lifecycle Events)。
CAPL 编程系列教程 - 第二十一期:系统测量事件详解
一、 课程回顾与本期目标
- 回顾: 上一期(第二十期)系统性地介绍了 CAPL 的事件驱动模型和常见的事件分类。
- 本期目标: 通过编写和运行示例代码,详细理解并观察四种主要的系统测量事件的触发时机、执行顺序以及各自的用途和限制。
二、 系统测量事件回顾
- 这类事件与 CANoe/CANalyzer 的测量过程(从启动到停止)的生命周期紧密相关。
- 主要包括四个事件:
on preStart: 测量即将开始之前触发。on start: 测量正式开始时触发。on preStop: 测量即将结束之前(收到停止请求后)触发。on stopMeasurement: 测量完全停止之后触发。
三、 各事件的用途与限制详解及示例
-
on preStart- 触发时机: 点击 CANoe 启动按钮后,在 CANoe 真正开始连接总线、收发报文之前。
- 用途: 执行准备工作,如读取配置文件、加载测试数据、初始化非总线相关的变量等
。 - 限制: 不能在此事件处理程序中执行任何总线操作,特别是发送报文 (
output())。因为此时测量尚未开始,与总线的连接还未就绪。尝试发送会报错(不允许输出到总线系统) 。 - 示例代码:
Code snippet
on preStart { write("***** PreStart 事件发生了 *****"); write("写一些读取配置文件、数据文件的代码"); // message 0x123 msg1; msg1.EngineSpeed = 2000; output(msg1); // 此处 output 会报错! }
-
on start- 触发时机: 紧随
on preStart之后,当 CANoe 准备就绪,可以正式开始测量、收发总线报文时触发。 - 用途: 执行测量开始时的初始化总线操作,例如:
- 启动周期性发送报文的定时器。
- 发送初始状态报文。
- 设置仿真节点的初始状态。
- 限制: 无明显限制,可以进行正常的总线操作。
- 示例代码:
Code snippet
on start { message EngineState msg1; // 假设 DBC 已加载 write("***** Start 事件发生了 *****"); write("已经可以发送报文了"); msg1.EngineSpeed = 2000; // 设置信号 msg1.OnOff = 1; output(msg1); // 在 on start 中发送报文是允许的 }
- 触发时机: 紧随
-
on preStop- 触发时机: 当用户点击 CANoe 停止按钮或程序触发停止测量时,在测量完全停止之前触发
。系统收到了停止请求,但尚未完全断开总线连接。 - 用途: 执行收尾工作,特别是需要在断开总线前完成的操作,例如:
- 发送“下线”或“状态保存”等通知报文给其他 ECU
。 - 保存当前状态到变量或临时文件。
- 发送“下线”或“状态保存”等通知报文给其他 ECU
- 限制/注意点:
- 在此事件中发送报文可能无法成功,因为事件处理程序执行很快,可能在报文还未完全发送出去时,测量就已经彻底停止了
。 - 解决方案: 使用
deferStop(ms)函数延迟测量的实际停止时间。 deferStop(5000);// 延迟 5000 毫秒 (5秒) 再完全停止测量。- 这给了 CAPL 脚本足够的时间来完成耗时的操作(如发送报文)。
- 在此事件中发送报文可能无法成功,因为事件处理程序执行很快,可能在报文还未完全发送出去时,测量就已经彻底停止了
- 示例代码:
Code snippet
on preStop { message 0x2BF msg2 = {dlc = 2}; // 自定义报文 write("***** PreStop 事件发生了 *****"); write("做一些收尾、通知其他 ECU 的代码工作"); msg2.byte(0) = 0x5C; msg2.byte(1) = 0x17; deferStop(5000); // 延迟 5 秒停止,确保报文有时间发送 output(msg2); // 发送收尾报文 }
- 触发时机: 当用户点击 CANoe 停止按钮或程序触发停止测量时,在测量完全停止之前触发
-
on stopMeasurement- 触发时机: 在
on preStop事件处理(包括deferStop的延迟)完成之后,当 CANoe 完全停止测量,与总线彻底断开连接时触发。 - 用途: 执行测量完全结束后的工作,例如:
- 对整个测量过程中收集的数据进行最终统计、分析
。 - 生成测试报告。
- 清理资源。
- 对整个测量过程中收集的数据进行最终统计、分析
- 限制: 不能再进行任何总线操作(如发送报文)
。 - 示例代码:
Code snippet
on stopMeasurement { write("***** StopMeasurement 事件触发了 *****"); write("做一些最后统计的代码工作"); }
- 触发时机: 在
四、 事件执行顺序演示
- 启动时:
on preStart->on start - 运行时: (处理其他事件如
on timer,on message等) - 停止时:
on preStop-> (deferStop延迟) ->on stopMeasurement - 通过在每个事件处理程序中加入
write()输出,可以清晰地观察到这个执行顺序。
五、 总结与后续
- 本期通过实例详细讲解了四个系统测量事件 (
on preStart,on start,on preStop,on stopMeasurement) 的触发时机、顺序、用途和关键限制。 - 特别强调了
on preStart不能发送报文,以及在on preStop中发送报文时通常需要配合deferStop()使用。 - 下一期: 将讲解核心的报文接收事件
on message。