CAPL 编程系列教程的第二十四期内容,继续讲解 CAPL 中的事件 (Events),本期重点是与系统变量 (System Variables) 相关的两个事件:on sysvar 和 on sysvar_update。
CAPL 编程系列教程 - 第二十四期:事件之 on sysvar 与 on sysvar_update
一、 课程回顾与本期目标
- 回顾: 前面学习了 CAPL 的事件驱动模型、系统测量事件、报文接收事件 (
on message)、信号事件 (on signal,on signal_update)。 - 本期目标: 学习与系统变量 (System Variables) 相关的事件
on sysvar和on sysvar_update,理解它们的触发条件、语法,以及如何在 CAPL 中创建、修改和响应系统变量。
二、 系统变量 (System Variables) 概述
- 是什么: 系统变量是 CANoe 中用于全局存储数据的一种机制
。它们由用户在 CANoe 环境中定义和管理,可以持久化保存在项目工程配置中 。 - 主要用途:
- 数据共享与存储: 在不同的 CAPL 节点、测试模块、面板之间共享数据,或者存储一些自定义的计算结果或状态
。 - 连接分析窗口: 可以在 CANoe 的分析窗口(如 Graphics, Data)中添加系统变量,像观察信号一样观察其值的变化
。例如,可以计算一个“预计碰撞时间 (TTC)”并存入系统变量,然后在 Graphics 窗口中绘图 。 - 连接仿真面板 (Panel): 这是系统变量非常重要的应用场景。可以将面板上的控件(如开关、滑块、输入框)与系统变量关联 (绑定)。当用户操作控件时,关联的系统变量值会自动改变;反之,通过 CAPL 修改系统变量的值,也可以更新面板控件的显示
。这是实现仿真面板交互逻辑的关键。
- 数据共享与存储: 在不同的 CAPL 节点、测试模块、面板之间共享数据,或者存储一些自定义的计算结果或状态
三、 在 CANoe 中创建系统变量
- 位置: CANoe 菜单 ->
Environment(环境) ->System Variables(系统变量)。 - 创建步骤:
- 在 System Variables 配置窗口中,可以右键 ->
New创建。 - 命名空间 (Namespace): 为了组织和避免命名冲突,通常会先创建命名空间(相当于分组),然后在命名空间下创建变量
。示例中创建了名为 Control的命名空间。 - 变量定义:
- 名称 (Name): 变量的名称 (如
TurnLeftIndicator)。 - 数据类型 (Data Type): 选择变量的数据类型(如
Integer,Float,String,Data等)。示例中选择了无符号整数 (Unsigned Integer) 。 - 初始值 (Initial Value): 设置变量的初始值
。 - 范围 (Min/Max): (可选) 设置变量的允许范围
。 - 单位 (Unit): (可选) 设置单位
。 - 值表 (Value Table): (可选) 为整数或枚举类型的变量定义值与文本描述的映射关系(如 0 对应 "Off", 1 对应 "On"),增强可读性
。
- 名称 (Name): 变量的名称 (如
- 保存: 创建或修改后需要保存配置,系统变量信息会存入工程文件
。
- 在 System Variables 配置窗口中,可以右键 ->
四、 在 CAPL 中访问和修改系统变量
- 访问/修改方式:
@符号 + 变量全名 (推荐):- 语法:
@Namespace::VariableName - 使用
@符号后跟系统变量的完全限定名称(包含命名空间,用::分隔)来直接读取或写入变量的值。 - 优点: 语法简洁直观
。 - 示例 (赋值):
@Control::TurnLeftIndicator = 1; - 示例 (读取):
currentValue = @Control::TurnLeftIndicator;
- 语法:
sysSetVariable<Type>()/sysGetVariable<Type>()系列函数:- 设置值函数:
sysSetVariableInt(Namespace, VariableName, Value);,sysSetVariableFloat(...),sysSetVariableString(...)等。 - 获取值函数:
sysGetVariableInt(Namespace, VariableName);,sysGetVariableFloat(...)等。 - 参数: 通常需要分别提供命名空间(字符串)、变量名(字符串)和值
。 - 优点: 函数名明确区分了操作类型和数据类型。
- 缺点: 写法相对
@方式更繁琐。 - 示例 (赋值):
sysSetVariableInt("Control", "TurnLeftIndicator", 0); - 示例 (读取):
currentValue = sysGetVariableInt("Control", "TurnLeftIndicator");
- 设置值函数:
- 注意: 访问系统变量时通常必须包含命名空间(如果定义了的话)
。教程中提到旧版本可能允许省略,但当前演示的版本需要写全名 。
五、 系统变量相关事件详解
-
on sysvar <Namespace::VariableName>- 触发时机: 仅当指定的系统变量
<Namespace::VariableName>的值发生变化时(新值与旧值不同)才会触发一次。 - 逻辑: 如果变量被重复赋予相同的值,该事件不会被触发。
- 用途: 主要用于响应系统变量状态的实际改变,例如响应面板控件状态切换后执行相应动作
。 - 语法:
Code snippet
on sysvar Control::TurnLeftIndicator { // 当该变量的值发生变化时执行 // ... 处理代码 ... }
- 触发时机: 仅当指定的系统变量
-
on sysvar_update <Namespace::VariableName>- 触发时机: 只要指定的系统变量
<Namespace::VariableName>被赋值(更新),无论其值是否发生变化,都会触发一次。 - 逻辑: 即使给变量赋了与当前相同的值,只要执行了赋值操作,就会触发此事件
。 - 用途: 当需要每次变量被设置(即使值不变)都执行某些操作时使用,相对
on sysvar用得较少。 - 语法:
Code snippet
on sysvar_update Control::TurnLeftIndicator { // 当该变量被更新(赋值)时执行 // ... 处理代码 ... }
- 触发时机: 只要指定的系统变量
- 对比:
on sysvar关注值的变化,on sysvar_update关注每次赋值/更新动作。
六、 在事件处理程序中获取变量值 (this 关键字)
this的含义: 在on sysvar或on sysvar_update事件处理程序的代码块内部,关键字this代表当前触发事件的那个系统变量的值。 this的类型: 与信号事件类似,this返回的是变量值的浮点数 (float或double) 表示,即使变量定义为整数。 - 获取值:
this: 直接获取变量的当前值(浮点数)。- 注意: 教程中提到也可以用
@方式或sysGetVariable<Type>函数在事件内部获取当前值,并演示了其结果与this相同。
- 类型转换: 如果需要将
this获取的值作为整数使用,需要进行强制类型转换(int)。 - 示例:
(注:Code snippeton sysvar Control::TurnLeftIndicator { write("变量 %s::%s 发生变化,当前值(float)=%f, 值(int)=%d", this.Namespace, // .Namespace 获取命名空间 (可能需要验证此属性) this.Name, // .Name 获取变量名 (可能需要验证此属性) this, // 直接用 this 获取浮点值 (int)this); // 强制转为整数 // 或者用 @ 获取 write("使用 @ 获取值: %d", @Control::TurnLeftIndicator); }.Namespace和.Name属性在this上的可用性需在实际环境中验证,视频中未直接使用这两个属性,而是直接打印了变量名字符串。)
七、 示例与演示
- 教程演示了:
- 在 CANoe 中创建名为
Control::TurnLeftIndicator的无符号整型系统变量,并设置了值表 (0=Off, 1=On)。 - 在 CAPL 的
on key 'a'事件中,使用@方式或sysSetVariableInt函数给该系统变量随机赋 0 或 1 的值。 - 在 Graphics 和 Data 窗口中添加该系统变量进行观察
。 - 编写
on sysvar Control::TurnLeftIndicator和on sysvar_update Control::TurnLeftIndicator事件处理程序,并在其中使用write()输出信息以及用不同方式获取变量值。 - 通过按 'A' 键不断改变(或更新)系统变量的值,观察 Write 窗口中两个事件的触发情况,清晰展示了
on sysvar(值变了才触发) 和on sysvar_update(每次赋值都触发) 的区别。
- 在 CANoe 中创建名为
八、 总结与后续
- 本期学习了 CANoe 系统变量的概念、创建方法及其在 CAPL 中的访问和修改方式 (
@和sysSet/GetVariable函数)。 - 重点掌握了响应系统变量变化的两个事件
on sysvar和on sysvar_update的区别与用法,以及如何在事件中使用this获取变量值。 - 系统变量及其事件是实现 CAPL 与 CANoe 面板交互、进行复杂数据处理和状态管理的重要基础。
- CAPL 事件部分的讲解基本结束。