CAPL 编程系列教程 - 第二十四期:事件之 on sysvar 与 on sysvar_update

CAPL 编程系列教程的第二十四期内容,继续讲解 CAPL 中的事件 (Events),本期重点是与系统变量 (System Variables) 相关的两个事件:on sysvaron sysvar_update

CAPL 编程系列教程 - 第二十四期:事件之 on sysvar 与 on sysvar_update

一、 课程回顾与本期目标

  • 回顾: 前面学习了 CAPL 的事件驱动模型、系统测量事件、报文接收事件 (on message)、信号事件 (on signal, on signal_update)。
  • 本期目标: 学习与系统变量 (System Variables) 相关的事件 on sysvaron sysvar_update,理解它们的触发条件、语法,以及如何在 CAPL 中创建、修改和响应系统变量。

二、 系统变量 (System Variables) 概述

  1. 是什么: 系统变量是 CANoe 中用于全局存储数据的一种机制 。它们由用户在 CANoe 环境中定义和管理,可以持久化保存在项目工程配置中
  2. 主要用途:
    • 数据共享与存储: 在不同的 CAPL 节点、测试模块、面板之间共享数据,或者存储一些自定义的计算结果或状态
    • 连接分析窗口: 可以在 CANoe 的分析窗口(如 Graphics, Data)中添加系统变量,像观察信号一样观察其值的变化 。例如,可以计算一个“预计碰撞时间 (TTC)”并存入系统变量,然后在 Graphics 窗口中绘图
    • 连接仿真面板 (Panel): 这是系统变量非常重要的应用场景。可以将面板上的控件(如开关、滑块、输入框)与系统变量关联 (绑定)。当用户操作控件时,关联的系统变量值会自动改变;反之,通过 CAPL 修改系统变量的值,也可以更新面板控件的显示 。这是实现仿真面板交互逻辑的关键。

三、 在 CANoe 中创建系统变量

  1. 位置: CANoe 菜单 -> Environment (环境) -> System Variables (系统变量)
  2. 创建步骤:
    • 在 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"),增强可读性
    • 保存: 创建或修改后需要保存配置,系统变量信息会存入工程文件

四、 在 CAPL 中访问和修改系统变量

  1. 访问/修改方式:
    • @ 符号 + 变量全名 (推荐):
      • 语法: @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");
    • 注意: 访问系统变量时通常必须包含命名空间(如果定义了的话)。教程中提到旧版本可能允许省略,但当前演示的版本需要写全名

五、 系统变量相关事件详解

  1. on sysvar <Namespace::VariableName>

    • 触发时机: 仅当指定的系统变量 <Namespace::VariableName>值发生变化时(新值与旧值不同)才会触发一次
    • 逻辑: 如果变量被重复赋予相同的值,该事件不会被触发。
    • 用途: 主要用于响应系统变量状态的实际改变,例如响应面板控件状态切换后执行相应动作
    • 语法:
      Code snippet
      on sysvar Control::TurnLeftIndicator { // 当该变量的值发生变化时执行
          // ... 处理代码 ...
      }
      
  2. on sysvar_update <Namespace::VariableName>

    • 触发时机: 只要指定的系统变量 <Namespace::VariableName> 被赋值(更新)无论其值是否发生变化,都会触发一次
    • 逻辑: 即使给变量赋了与当前相同的值,只要执行了赋值操作,就会触发此事件
    • 用途: 当需要每次变量被设置(即使值不变)都执行某些操作时使用,相对 on sysvar 用得较少
    • 语法:
      Code snippet
      on sysvar_update Control::TurnLeftIndicator { // 当该变量被更新(赋值)时执行
          // ... 处理代码 ...
      }
      
  • 对比: on sysvar 关注值的变化on sysvar_update 关注每次赋值/更新动作

六、 在事件处理程序中获取变量值 (this 关键字)

  • this 的含义: 在 on sysvaron sysvar_update 事件处理程序的代码块内部,关键字 this 代表当前触发事件的那个系统变量的值
  • this 的类型: 与信号事件类似,this 返回的是变量值的浮点数 (floatdouble) 表示,即使变量定义为整数
  • 获取值:
    • this: 直接获取变量的当前值(浮点数)。
    • 注意: 教程中提到也可以用 @ 方式或 sysGetVariable<Type> 函数在事件内部获取当前值,并演示了其结果与 this 相同
  • 类型转换: 如果需要将 this 获取的值作为整数使用,需要进行强制类型转换 (int)
  • 示例:
    Code snippet
    on 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::TurnLeftIndicatoron sysvar_update Control::TurnLeftIndicator 事件处理程序,并在其中使用 write() 输出信息以及用不同方式获取变量值
    • 通过按 'A' 键不断改变(或更新)系统变量的值,观察 Write 窗口中两个事件的触发情况,清晰展示了 on sysvar (值变了才触发) 和 on sysvar_update (每次赋值都触发) 的区别

八、 总结与后续

  • 本期学习了 CANoe 系统变量的概念、创建方法及其在 CAPL 中的访问和修改方式 (@sysSet/GetVariable 函数)。
  • 重点掌握了响应系统变量变化的两个事件 on sysvaron sysvar_update 的区别与用法,以及如何在事件中使用 this 获取变量值。
  • 系统变量及其事件是实现 CAPL 与 CANoe 面板交互、进行复杂数据处理和状态管理的重要基础。
  • CAPL 事件部分的讲解基本结束。