零基础学习CAPL-CAN&LIN信号与系统&环境变量的使用

CAPL中信号与变量使用详解

1. CAN信号

CAN信号是封装在CAN报文中的数据片段。

1.1 定义

CAN信号在CANdb(.dbc)文件中定义,包括:

  • 信号名称、长度(位)
  • 字节顺序(Intel/Motorola)
  • 精度(因子)、偏移量
  • 最小值、最大值、单位

1.2 在CAPL中的使用

读取信号物理值:

on message EngineData
{
  // 直接使用信号名读取物理值
  float currentRPM = EngineSpeed;
  int currentTemp = EngineTemperature;
  
  // 使用this关键字
  float currentRPM = this.EngineSpeed;
  
  write("当前转速: %f rpm", currentRPM);
}

读取信号总线值(使用$):

on message EngineData
{
  // 使用$读取信号的总线值
  long rawRPM = $EngineSpeed;
  float physicalRPM = EngineSpeed;
  
  write("原始值: %d, 物理值: %f", rawRPM, physicalRPM);
}

赋值/写入:

on key 'a'
{
  // 设置信号物理值
  BodyControl.LightSwitch = 1;
  output(BodyControl);
  
  // 设置信号总线值
  $BodyControl.LightSwitch = 0xFF;
  output(BodyControl);
}

1.3 使用场景

  • 常规数据处理使用物理值(直接信号名)
  • 校验和、多路复用器、诊断等底层处理使用总线值($信号名)

2 LIN信号

LIN信号存在于LIN帧中,定义在LDF(.ldf)文件中。

2.1 在CAPL中的使用

读取:

on linFrame MyLinFrame
{
  // 读取物理值
  byte doorStatus = DoorContact;
  
  // 读取总线值
  byte rawDoorStatus = $DoorContact;
  
  write("车门状态: %d (原始值: %d)", doorStatus, rawDoorStatus);
}

赋值/写入:

on key 'b'
{
  // 设置物理值
  MyLinFrame.InteriorLight = 50;
  output(MyLinFrame);
  
  // 设置总线值
  $MyLinFrame.InteriorLight = 0x7F;
  output(MyLinFrame);
}

3 系统变量

系统变量是CANoe内部使用的全局变量,用于在不同模块间传递数据。

3.1 定义

在System Variable Group (SVG) 文件中定义。

3.2 在CAPL中的使用(使用@符号)

读取:

on sysvar MyNamespace::EngineState
{
  // 使用@读取系统变量
  int state = @MyNamespace::EngineState;
  write("引擎状态变为: %d", state);
}

void myFunction()
{
  int currentState = @MyNamespace::EngineState;
}

赋值/写入:

on key 'c'
{
  // 使用@设置系统变量
  @Sysvar::CarCockpit::Ignition = 1;
  @Sysvar::Display::Message = "系统就绪";
  @Debug::MotorValue::EngineSpeed = $EngineSpeed;
}

常见相关函数
使用以SysGetVariable开头和SysSetVariable开头的访问函数。
如SysGetVariableInt、SysGetVariableFloat、SysSetVariableInt、SysSetVariableFloat;
系统变量的初始值需要定义明确。如果在使用过程中没有定义初始值,如果涉及到系统变量reset,那么将无法完成reset功能。

4 环境变量

环境变量用于CANoe与外部环境的交互。

4.1 定义

在Environment Variable窗口中定义。

4.2 在CAPL中的使用

环境变量和系统变量用法类似;
比较通用的访问操作方式是使用函数getValue()和putValue()
注意事项:

  1. 环境变量的使用必须要以DBC的格式来使用,并且需要将DBC添加到CAN网络中。
  2. 环境变量在CANoe 12.0版本之后不适用。

读取:

on envVar MyEnvironmentVar
{
  long value;
  getValue(MyEnvironmentVar, value);
  write("环境变量值变为: %d", value);
}

void readEnvVar()
{
  long val;
  getValue(MyEnvironmentVar, val);
}

赋值/写入:

on key 'd'
{
  putValue(ExternalControl, 100);
}

5 系统变量和环境变量

相同点:

  1. 都可以作为ECU、面板和CAPL程序相连接的媒介。
  2. 直接引用时都要添加@符号;

不同点:
系统变量有命名空间的概念,而环境变量则没有这种概念
环境变量:@envKL30
系统变量:@sysvar::EngineModule::EngineSpeed
注意系统变量其实可以理解为sysvar,是一个命名空间,然后又嵌套了一个名为EngineModule的命名空间。

6 $ 与 @ 符号的详细对比

6.1 $符号 - 信号总线值访问

用途: 访问CAN/LIN信号的总线值

使用场景:

  1. 多路复用报文处理
on message MultiplexedMessage
{
  switch($MuxSignal)  // 读取MUX原始值
  {
    case 0:
      value1 = SignalA;        // 物理值
      rawValue1 = $SignalA;    // 原始值
      break;
    case 1:
      value2 = SignalB;
      break;
  }
}
  1. 校验和计算
on message MyMessage
{
  byte checksum = $Signal1 + $Signal2 + $Signal3;
  if(checksum != $ChecksumSignal)
  {
    write("校验和错误!计算值: %d, 接收值: %d", checksum, $ChecksumSignal);
  }
}

6.2 @符号 - 系统变量访问

用途: 访问系统变量的物理值

使用场景:

  1. 响应系统变量变化
on sysvar EngineState
{
  int state = @EngineState;    // 使用@读取系统变量
  write("引擎状态变为: %d", state);
  
  if(state == 2)
  {
    @Sysvar::Display::Message = "引擎已启动";  // 使用@设置系统变量
  }
}
  1. 测试用例控制
testcase CheckEngineStart()
{
  @Ignition = 1;      // 设置系统变量
  @Starter = 1;
  
  TestWaitForTimeout(3000);
  if(@EngineSpeed > 500)  // 读取系统变量
  {
    TestStepPass("引擎成功启动");
  }
}

6.3 核心区别总结

特性$ 符号@ 符号
变量类型CAN/LIN信号(原始值)系统变量
代表的值报文中信号的原始值系统变量的物理值
数据类型通常是long(整数)取决于系统变量定义(int, float, string等)
使用场景校验和、多路复用器、诊断等底层处理系统状态控制、HMI交互、模块间通信
访问方式$SignalName@SysvarName
值转换原始值 × 因子 + 偏移量 = 物理值直接操作物理值

7 应用示例

variables
{
  message EngineMsg * myEngineMsg = {dlc = 8};
}

on sysvar Sysvar::StartSimulation
{
  // 系统变量控制仿真启动
  if (@Sysvar::StartSimulation == 1)
  {
    putValue(ExtApp_StartCommand, 1);  // 环境变量通知外部程序
  }
}

on envVar ExtApp_TargetSpeed
{
  // 环境变量接收外部指令
  long targetSpeed;
  getValue(ExtApp_TargetSpeed, targetSpeed);
  
  // 转换为CAN信号(使用物理值)
  myEngineMsg.TargetSpeed = targetSpeed;
  output(myEngineMsg);
  
  // 使用原始值进行校验和计算
  $myEngineMsg.Checksum = calculateChecksum();
  output(myEngineMsg);
  
  // 更新系统变量用于显示
  @Sysvar::Display::TargetSpeed = targetSpeed;
}

on message VehicleSpeed
{
  // 处理CAN信号
  float physicalSpeed = VehicleSpeed;      // 物理值
  long rawSpeed = $VehicleSpeed;           // 原始值
  
  // 更新系统变量显示
  @Sysvar::Display::ActualSpeed = physicalSpeed;
  
  // 使用原始值进行诊断检查
  if(rawSpeed == 0xFFFF)
  {
    @Sysvar::Errors::InvalidSpeed = 1;
  }
}

long calculateChecksum()
{
  // 使用原始值计算校验和
  return ($Signal1 + $Signal2 + $Signal3) & 0xFF;
}

8 关键要点总结

  1. 正确选择变量类型

    • 总线通信:CAN/LIN信号
    • 内部状态管理:系统变量
    • 外部系统集成:环境变量
  2. 正确使用访问符号

    • 信号物理值:直接使用信号名
    • 信号原始值:$信号名
    • 系统变量:@变量名SysGetVariableInt/SysGetVariableFloat/SysSetVariableInt/SysSetVariableFloat
    • 环境变量:@变量名getValue()/putValue()
  3. 值转换关系

    • 物理值 = (原始值 × 因子) + 偏移量
    • 原始值 = (物理值 - 偏移量) / 因子
特性CAN 信号LIN 信号系统变量环境变量
来源/定义CANdb (.dbc) 文件LDF (.ldf) 文件System Variable GroupEnvironment Variable
作用域特定CAN报文特定LIN帧全局(CANoe内部)全局(CANoe与外部)
主要用途在CAN总线上交换数据在LIN总线上交换数据CANoe内部模块间数据共享和状态管理与外部应用或硬件(VT)交互
CAPL读取直接使用信号名(读取物理值)、$信号名(读取总线值)直接使用信号名(读取物理值)、$信号名(读取总线值)@变量名、SysGetVariableInt、SysGetVariableFloat@变量名getValue(变量名, value)
CAPL写入报文.信号 = 物理值; $报文.信号 = 总线值; output(报文);帧.信号 = 物理值;$报文.信号 = 总线值; output(帧);@变量名 = 值;、SysSetVariableInt、SysSetVariableFloat@变量名 = 值;putValue(变量名, 值);
触发事件on messageon linFrameon sysvaron envVar
核心区别总线数据,物理通信总线数据,物理通信内部状态,逻辑控制外部接口,系统集成

理解这些区别和正确使用方法,对于编写高效、可靠的CAPL脚本至关重要。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

车载测试工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值