Vector - CAPL - 实时时间on *

前面有简单的提到过on message的用法,但是对于整个on *家族来说,on message仅仅这是其中之一,为了能够的了解、学习这个家族的成员,因此做了专门的整理的,将囊括CALP用常用的所有的on *家族成员,并对其进行了简单的分类。

一、事件类

  1. on message

on message *

*:代表总线出现的任意报文信息

下面是一个非常无聊代码,表示总线上收到任意信息,立马将这个信息再次发出去,有点像路由,但是毫不沾边;不过在这个上面稍微优化一下倒是可以做成一个模拟路由;

on message * 
{
  output(this);
}

路由代码:

on message * 
{
  message CAN1.* msg1;
  message CAN2.* msg2;
  if(this.id < 0x200)
  {
    msg2 = this
    output(msg2);
  }
  else
  {
    msg1 = this
    output(msg1);
  }
}
on message CAN1.*

另外一种方法实现网关的功能;CAN1上出现报文立马发送到CAN2;CAN2出现报文立马发送到CAN1,非常简单又使用的一种方法。

on message CAN1.*
{
   message CAN2.* msg;
   if(this.dir != rx) return; 
   msg = this;
 output(msg);
}

on message CAN2.*
{
   message CAN1.* msg;
   if(this.dir != rx) return; 
   msg = this;
 output(msg);
}
on message 0x100

当总线出现确定id的报文消息,打印接收到该消息内容和接收到的相对时间信息;这里的0x100可以是十进制的100/100x或者16进制的0x100/0x100x都是支持的。

on message 0x100
{
  write("this id = 0x%x,[%x][%x][%x][%x][%x][%x][%x][%x] time = %f",
  this.id, this.byte(0), this.byte(1), this.byte(2), this.byte(3)
  , this.byte(4), this.byte(5), this.byte(6), this.byte(7),timeNow());
}
on message EngineData

相较于上面on message 100这种类型,on message EngineData需要加入dbc,并且dbc中包含报文名称为EngineData,实际使用功能是一样的,不过on message EngineData与项目更加贴合,做兼容性较难,个人不太喜欢使用。

on message EngineData
{
  write("this id = 0x%x,[%x][%x][%x][%x][%x][%x][%x][%x] time = %f",
  EngineData.id, EngineData.byte(0), EngineData.byte(1), EngineData.byte(2),EngineData.byte(3)
  , EngineData.byte(4), EngineData.byte(5), EngineData.byte(6), EngineData.byte(7),timeNow());
}
on message 0,1 ,10-20

对总线上出现报文id为0,1,10-20之间的任意id都会触发该响应,进入到内部处理,这种可以在测试28服务的时候去使用,检测速度和效果会相当的好。

on message 0,1 ,10-20
{
  write("this id = 0x%x,[%x][%x][%x][%x][%x][%x][%x][%x] time = %f",
  this.id, this.byte(0), this.byte(1), this.byte(2), this.byte(3)
  , this.byte(4), this.byte(5), this.byte(6), this.byte(7),timeNow());
}
组合用法

将on message作为过滤器使用,例如除去报文0x123,其他的报文都将重新发至CAN总线上:

on message 500 
{ 
}
on * 
{
  output(this);
}

注意:在时间调用过程中,关键字this只能用在输出函数和读取当前时间戳,无法对this的内容进行修改。

  1. on errorFrame

错误帧处理程序是在接收到错误帧或过载帧之后调用的。

如果使用启用CAN FD ISO的硬件接口,则在发生协议异常时也会调用处理程序。如果CAN控制器设置为限制模式并发生错误,或者如果启用了协议异常处理,则会发出协议异常信号。在前一种情况下,可以使用错误代码来找出错误的类型。在后一种情况下,错误代码被设置为协议异常。这意味着,CAN控制器已经在经典CAN模式下接收到CAN FD帧(帧的FDF位是隐性的),或者CAN FD帧中的res位是隐性;

板上CAPL的错误帧处理程序仅适用于其驱动程序将错误帧传输到板上CAPL的设备。

以下代码将错误代码和错误帧的方向作为格式化字符串输出到写入窗口。

on errorFrame
{
  const int bufferSize = 256;
  char buffer[bufferSize];
  char cdirection[2][3] = {"RX", "TX"};
  int ndir;
  word ecc;
  word extInfo;
  int isProtocolException;

  ecc = (this.ErrorCode >> 6) & 0x3f;
  extInfo = (this.ErrorCode >> 12) & 0x3;
  isProtocolException = (this.ErrorCode & (1 << 15)) != 0;

  ndir = extInfo == 0 || extInfo == 2 ? 0 : 1; //set ndir to 0 for RX and to 1 for TX

  if(this.CtrlType == 1){
    //SJA1000 specific
    switch (ecc){
    case 0: snprintf(buffer, bufferSize, "Bit error"); break;
    case 1: snprintf(buffer, bufferSize, "Form error"); break;
    case 2: snprintf(buffer, bufferSize, "Stuff error"); break;
    case 3: snprintf(buffer, bufferSize, "Other error"); break;
    default: snprintf(buffer, bufferSize, "Unknown error code");
    }
  }
  else if(this.CtrlType == 2){
    //CAN core specific
    switch (ecc){
      case 0: snprintf(buffer, bufferSize, "Bit error"); break;
      case 1: snprintf(buffer, bufferSize, "Form error"); break;
      case 2: snprintf(buffer, bufferSize, "Stuff error"); break;
      case 3: snprintf(buffer, bufferSize, "Other error"); break;
      case 4: snprintf(buffer, bufferSize, "CRC error"); break;
      case 5: snprintf(buffer, bufferSize, "ACK Del. error"); break;
      case 7:
      {
        switch (extInfo){
        case 0: snprintf(buffer, bufferSize, "RX NACK error (recessive error flag)"); break;
        case 1: snprintf(buffer, bufferSize, "TX NACK error (recessive error flag)"); break;
        case 2: snprintf(buffer, bufferSize, "RX NACK error (dominant error flag)"); break;
        case 3: snprintf(buffer, bufferSize, "TX NACK error (dominant error flag)"); break;
      }
      break;
    }
    case 8: snprintf(buffer, bufferSize, "Overload frame"); break;
    case 9: snprintf(buffer, bufferSize, "FDF or res recessive"); break; //protocol exception specific
    default: snprintf(buffer, bufferSize, "Unknown error code"); break;
    }
  }
  else snprintf(buffer, bufferSize, "Unsupported CAN controller");

  if(isProtocolException){
    write("Protocol exception on CAN%d at %fs: %s", this.can, this.time/1e5, buffer);
  }
  else{
    write("%s error frame on CAN%d at %fs: %s", cdirection[ndir], this.can, this.time/1e5, buffer);
  }
}

Bit

Interfaces with CAN Core

Interfaces with SJA1000

0-4

not used

Segment

5

Direction

Direction

1: RX

1: RX

6-11

Error Code

Error Code

Value

Description

Value

Description

0

Bit Error

0

Bit Error

1

Form Error

1

Form Error

2

Stuff Error

2

Stuff Error

3

Other Error

3

Other Error

4

CRC Error

5

Ack Del Error

6

not used

7

Ack Error

8

Overload Frame

9

Protocol Exception Event

12-13

Extended Information

Extended Information

Value

Description

Value

Description

0

RX NAK Error.

0

not used

Passive Error Flag, if Error Code is Ack Error.

1

TX NAK Error.

1

not used

Passive Error Flag, if Error Code is Ack Error.

2

RX Error.

2

RX Error

Active Error Flag, if Error Code is Ack Error.

3

TX Error.

3

TX Error

Active Error Flag, if Error Code is Ack Error.

14

1: The error frame was send by CANoe/CANalyzer, for example with output(errorFrame)

Not used

15

1: Protocol exception

Not used

  1. on signal

通过信号名称的变化,获取信号的相关信息:

on signal LightSwitch::OnOff
{
  v1 = this.raw;
  v2 = $LightSwitch::OnOff.raw;
}

信号表示的几种方法:

//如果仅通过信号名无法进行唯一识别,则需要进一步进行溯源,方法如下:
[(channel | network)::][[dbNode::]node::][[dbMsg::]message::][dbSig::]signal
// Node + Signal
$LightSwitch::OnOff              
// Node + Message + Signal
$LightSwitch::LightState::OnOff  
// Channel + Node + Signal
$CAN1::Gateway::Status           
// Network + Node + Signal
$PowerTrain::Gateway::Status     
// Channel + Signal
$CAN1::Status                    
  1. on signal change/update

如果需要多个信号同时改变才会触发某个事件,则可以通过以下方法进行判断使用:

on signal ( signalname1 | signalname2 | ...)

on signal ( LightSwitch::OnOff | MotorSwitch::OnOff )
{
    v1 = this.raw;
    v2 = $LightSwitch::OnOff.raw;
}

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

车载网络测试

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

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

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

打赏作者

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

抵扣说明:

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

余额充值