Advertisement
Responsive Ad Slot (Vector Toolchains & Embedded Certifications)
🚗 Automotive System Focus: Anti-lock Braking System (ABS)

High-Frequency Wheel Speed Frame Construction

The ABS module transmits wheel speed data (WheelSpeed_FL, WheelSpeed_FR, WheelSpeed_RL, WheelSpeed_RR) at 10ms intervals on ID 0x1A0 with DLC 8. Each 16-bit word represents speed in 0.01 km/h. In CAPL, constructing and transmitting this frame involves setting the message identifier, DLC, populating the 8 data bytes, and calling `output()`.

Overview & Key Concepts

CAN Messages in CAPL Scripting (CAN Protocol in CAPL)

In CAPL (CAN Application Programming Language), a powerful language for automotive network testing, particularly used in the context of CAN (Controller Area Network) communication, "CAN messages" are a key element in designing tests, simulations, and communications between ECUs (Electronic Control Units). CAPL allows you to simulate CAN networks and exchange messages between ECUs, which is essential for automotive diagnostics, testing, and validation.

Message Types

Standard CAN Message: Identified by an 11-bit identifier.

Extended CAN Message: Identified by a 29-bit identifier.

Working with CAN Messages in CAPL

Defining a CAN Message in CAPL: In CAPL, CAN messages are defined using message keywords and can be interacted with either through predefined or custom CAN message objects. Basic Message Definition capl message TestMessage {

CAPL CAPL - Working with CAN Messages in CAPL
byte data[8];   // 8 bytes of data
}
Sending CAN Messages: You can send CAN messages with the output() function or send predefined messages using the send() function.
Example 1: Sending a Simple CAN Message
capl

variables {
message TestMessage msg;   // Define the message variable
}
on start {
// Initialize message data
msg.data[0] = 0x01;
msg.data[1] = 0x02;
msg.data[2] = 0x03;
msg.data[3] = 0x04;
msg.data[4] = 0x05;
msg.data[5] = 0x06;
msg.data[6] = 0x07;
msg.data[7] = 0x08;
// Send message on CAN bus
output(msg);
}
In this example:
A message TestMessage with an array data[8] is created.
The message is populated with hexadecimal values.
The output() function sends the message to the CAN network.
Sending Standard CAN Message Using send(): To send predefined CAN messages like CAN_Msg_1, CAN_Msg_2, etc., you can use the send() function, which works with messages configured in the CAN database (DBC file).
Example 2: Sending a CAN Message from DBC Database
capl

on start {
// Send a message named "EngineData" from the DBC file
send(EngineData);
}
In this case, EngineData is a message defined in the DBC file, and calling send() will transmit the message with all its data fields.
Receiving CAN Messages: You can receive CAN messages by specifying on message for predefined CAN messages or using the message event handler for custom messages.
Example 3: Receiving a CAN Message
capl

on message EngineData {
output("Received Engine Data:");
output("Engine RPM: %d", EngineData.RPM);
output("Engine Temp: %d", EngineData.Temperature);
}
Here:
The on message EngineData handler listens for incoming EngineData messages.

When the message is received, it outputs the RPM and temperature data to the log.

Setting Message Filters: CAPL allows filtering for specific CAN message IDs or certain conditions. Example 4: Filtering CAN Messages capl on message {

if (this.id == 0x100) {

CAPL CAPL - Working with CAN Messages in CAPL
output("Message with ID 0x100 received.");
}
}
In this example:
The on message event will be triggered for any message.

The if statement filters messages based on their ID (in this case, 0x100).

Using Message Timing: You can schedule periodic messages or delay sending messages using timers. Example 5: Periodic Sending of a CAN Message capl variables {

CAPL CAPL - Working with CAN Messages in CAPL
message TestMessage msg;
msTimer timer1;
}
on start {
setTimer(timer1, 1000);  // Set a timer for 1000ms (1 second)
}
on timer timer1 {
msg.data[0] = 0xAA;
msg.data[1] = 0xBB;
output(msg);   // Send message
setTimer(timer1, 1000);  // Reset the timer
}

Here, the message is sent every 1000 milliseconds using a timer.

Single Message Types

Define custom message types in CAPL using message to structure the data you need to send or receive.

CAN Signals

Signals are individual data fields within a CAN message. They represent specific parameters, such as speed, temperature, etc.

Example 6: Defining a Signal and Sending It capl message EngineData {

CAPL CAPL - CAN Signals
byte EngineSpeed;
byte EngineTemperature;
}
on start {
EngineData.EngineSpeed = 5000;     // RPM
EngineData.EngineTemperature = 90;  // Temperature in °C
output(EngineData);
}

This example defines a message EngineData with two signals: EngineSpeed and EngineTemperature.

Extended CAN Messages: Extended messages are supported in CAPL as well. The message ID is 29 bits in this case. Example 7: Sending an Extended CAN Message capl message ExtendedMessage {

CAPL CAPL - CAN Signals
byte data[8];
}
on start {
ExtendedMessage msg;
msg.data[0] = 0x01;
msg.data[1] = 0x02;
msg.data[2] = 0x03;
msg.data[3] = 0x04;
msg.data[4] = 0x05;
msg.data[5] = 0x06;
msg.data[6] = 0x07;
msg.data[7] = 0x08;
msg.id = 0x18FF0100;   // 29-bit ID for extended message
output(msg);
}

Conclusion

CAPL provides a powerful, flexible way to simulate, send, and receive CAN messages. It allows for detailed control over CAN network communication, enabling testing, simulation, and diagnostics of automotive systems. By combining message structures, signal handling, and timing, CAPL scripts can emulate real-world CAN networks and help automate testing processes.

⚠️ Common Pitfalls & CANoe Troubleshooting Tips
  • Forgetting to set `msg.dlc` defaults to 0 or uninitialized length in raw messages, resulting in truncated frames on the bus.
  • Extended 29-bit CAN IDs must have the extended flag set or use the 'x' suffix (e.g. `message 0x18FEF100x myMsg;`).
📝 Concept Mastery Assessment
12 Questions Score: 0 / 0

Select your answer for each question below to receive immediate correctness evaluation and in-depth technical rationale.

Question 1 of 12
How do you declare a CAN message variable with ID 0x123 in CAPL?
Explanation
'message 0x123 msg;' declares a CAN frame buffer initialized with message ID 0x123.
Question 2 of 12
Which built-in function transmits a prepared CAN message onto the bus in CAPL?
Explanation
'output(msg);' sends the message to the CAN controller transmit queue for arbitration on the bus.
Question 3 of 12
How do you access the first raw payload byte of a CAN message variable 'msg'?
Explanation
In CAPL, message bytes are accessed using the 'msg.byte(index)' member function, where index ranges from 0 to 7 (or 0 to 63 in CAN FD).
Question 4 of 12
What does the 'msg.dlc' property represent in a CAN message object?
Explanation
'msg.dlc' holds the Data Length Code specifying the payload byte count (up to 8 in Classical CAN, up to 64 in CAN FD).
Question 5 of 12
How do you set a CAN message to use an Extended 29-bit CAN ID rather than a Standard 11-bit ID?
Explanation
In CAPL, appending 'X' to the message ID literal (e.g. 0x18FEF100X) or setting the extended ID bit designates an extended 29-bit identifier.
Question 6 of 12
What property indicates whether an incoming message in 'on message' was received (Rx) or transmitted (Tx) by the node?
Explanation
'this.dir' indicates direction: RX for received messages from the bus, and TX for frames sent by the local node.
Question 7 of 12
How can you read a 16-bit word starting at byte offset 2 from a message 'msg' in CAPL?
Explanation
'msg.word(offset)' reads a 2-byte unsigned integer from the message payload starting at the given byte offset.
Question 8 of 12
What is the difference between declaring a raw message (message 0x200 msg;) and a symbolic message (message EngineData msg;)?
Explanation
Symbolic messages link to database definitions (DBC), allowing direct signal read/write by name with automatic scaling.
Question 9 of 12
Can you change the transmission channel of a message to CAN Channel 2 before outputting?
Explanation
'msg.can = 2;' designates CAN channel 2 as the transmission target for that message frame.
Question 10 of 12
What property stores the timestamp of message reception in an 'on message' handler?
Explanation
'this.time' holds the simulation timestamp (in 10-microsecond units) at which the frame was received.
Question 11 of 12
What is an RTR (Remote Transmission Request) frame in CAN and how is it flagged in CAPL?
Explanation
'msg.rtr = 1;' configures the frame as a Remote Transmission Request without data payload bytes.
Question 12 of 12
How do you specify a CAN FD message with 64-byte payload capability in CAPL?
Explanation
Setting 'msg.fdf = 1' (Flexible Data-rate Flag) enables CAN FD frame structure, allowing DLCs up to 64 bytes.
0 / 0 (0%)
Great job! Review the questions above and proceed when ready.
🛠️ Hands-on Automotive Challenge: Cyclic ABS Wheel Speed Frame Generator

Write a CAPL script that sets up a 10ms cyclic timer to transmit CAN message ID 0x1A0 (DLC 8). In each cycle, pack 16-bit speed values for Front-Left (50 km/h = 5000 raw) and Front-Right (50 km/h = 5000 raw) into bytes 0-3, increment an alive counter in byte 7 (0..15), and call `output()`.

Verified CAPL implementation:

CAPL Solution - Cyclic ABS Wheel Speed Frame Generator
variables {
  message 0x1A0 msgABS;
  msTimer tABS_Cycle;
  byte gAliveCounter = 0;
}

on start {
  msgABS.dlc = 8;
  setTimer(tABS_Cycle, 10); // 10ms periodic cycle
}

on timer tABS_Cycle {
  word rawSpeed = 5000; // 50.00 km/h

  // Front-Left Wheel Speed (Bytes 0-1, Big Endian)
  msgABS.byte(0) = (rawSpeed >> 8) & 0xFF;
  msgABS.byte(1) = rawSpeed & 0xFF;

  // Front-Right Wheel Speed (Bytes 2-3, Big Endian)
  msgABS.byte(2) = (rawSpeed >> 8) & 0xFF;
  msgABS.byte(3) = rawSpeed & 0xFF;

  // Alive counter in byte 7
  msgABS.byte(7) = gAliveCounter;
  gAliveCounter = (gAliveCounter + 1) % 16;

  output(msgABS);
  setTimer(tABS_Cycle, 10); // Re-arm timer
}
Advertisement
Responsive Ad Slot (Automotive Embedded Systems Career Resources)