Vector - CAPL - real time on *

The usage of on message was briefly mentioned before, but for the entire on * family, on message is only one of them. In order to be able to understand and learn the members of this family, a special arrangement has been made. Include all on * family members commonly used in CALP, and carry on a simple classification to them.

1. Event class

  1. on message

on message *

*: Represents any message information that appears on the bus

The following is a very boring code, which means that any information is received on the bus, and the information is sent again immediately, which is a bit like routing, but it has nothing to do with it; but a little optimization on this can be made into a simulated routing;

on message * 
{
  output(this);
}

Routing code:

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

on message CAN1.*

Another method is to realize the function of the gateway; when a message appears on CAN1, it is sent to CAN2 immediately; when a message appears on CAN2, it is sent to CAN1 immediately, which is a very simple and useful method.

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

When there is a message message with a certain id on the bus, print the content of the received message and the relative time information received; here 0x100 can be decimal 100/100x or hexadecimal 0x100/0x100x are supported.

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

Compared with the type of on message 100 above, on message EngineData needs to be added to dbc, and the name of the message contained in dbc is EngineData, the actual use function is the same, but on message EngineData is more suitable for the project, and it is more difficult to make compatibility , I personally don't like to use it.

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

Any id on the bus with a message id between 0, 1, 10-20 will trigger the response and enter the internal processing. This can be used when testing 28 services, and the detection speed and effect will be quite good .

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());
}

Combined usage

Use on message as a filter, for example, remove the message 0x123, and other messages will be resent to the CAN bus:

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

Note: During the time calling process, the keyword this can only be used in the output function and read the current timestamp, and the content of this cannot be modified.

  1. on errorFrame

The error frame handler is called after receiving an error frame or an overload frame.

If a CAN FD ISO-enabled hardware interface is used, the handler is also called when a protocol exception occurs. A protocol exception is signaled if the CAN controller is set to restricted mode and an error occurs, or if protocol exception handling is enabled. In the former case, the error code can be used to find out the type of error. In the latter case, the error code is set to the protocol exception. This means, the CAN controller has received a CAN FD frame in classic CAN mode (the FDF bit of the frame is recessive), or the res bit in the CAN FD frame is recessive;

The error frame handler on the on-board CAPL only applies to devices whose drivers transmit error frames to the on-board CAPL.

The following code outputs the error code and the direction of the error frame as a formatted string to the write window.

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

Error Ack

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;
}

おすすめ

転載: blog.csdn.net/weixin_54581097/article/details/129679354