Bus Jitter, Transmission Latency & Cycle Drift Analysis
In automotive networks, periodic messages must maintain strict cycle times. An engine status message specified at 20ms must not arrive at 15ms or 25ms due to bus arbitration delays or buffer congestion. CAPL timing scripts analyze arrival deltas and compute jitter statistics in real time.
Overview & Key Concepts
CAN Signals & Message Timing in CAPL (CAN Access Programming Language) Scripting
CAPL (CAN Access Programming Language) is a high-level programming language used for automotive and embedded system applications, particularly for CAN bus communication. In CAPL, signals and message timing play a crucial role in simulating and testing CAN communication systems.
Here, we will explain CAN Signals, Messages, and Timing in CAPL, followed by detailed examples.
CAN Signals and Messages in CAPL
A CAN signal represents a specific piece of data within a CAN message, while a CAN message is the entire frame of data that is transmitted over the CAN bus. CAPL allows you to interact with both signals and messages to simulate, test, or analyze the behavior of the CAN network.
A CAN message consists of several parts
Identifier (ID): The ID of the message, which determines the priority of the message.
Data: The actual data sent, represented as signals.
CRC: The cyclic redundancy check for error detection.
Control Information: Includes stuff bits, acknowledgement, etc.
For example, a CAN message in CAPL might look like this
cpp
message CanMessage1 {
// Message identifier (ID)
id = 0x123;
// Data length (8 bytes max for CAN 2.0)
dlc = 8;
// Signal 1 (e.g., temperature)
signal Temperature : int32;
// Signal 2 (e.g., pressure)
signal Pressure : float;
}
This message can represent a frame with two signals: Temperature and Pressure.
Signals in CAPL
Signals in CAPL are associated with a CAN message, and they define the data type and size. A signal is typically extracted from or assigned to a message. A signal's value can be changed or read during simulation or test.
Example of signal definition
cpp
variables
{
message CanMessage1 msg; // Define a message object
}
on message CanMessage1 // Event triggered on receiving the message
{
int32 temperature = msg.Temperature; // Accessing the signal
float pressure = msg.Pressure; // Accessing the signal
write("Received Temperature: %d, Pressure: %f", temperature, pressure);
}
In the above example:
CanMessage1 is a message type.
Temperature and Pressure are signals within that message.
When CanMessage1 is received, the on message event handler accesses the signal values.
Message Timing in CAPL
Message timing is critical for simulating and controlling how often messages are transmitted, how they interact, and how synchronization between different modules is achieved. CAPL offers various mechanisms to work with timing, including timers, event handling, and signal changes.
Example of Timing with Timer
cpp
variables
{
msTimer messageTimer; // Define a timer
}
on start
{
setTimer(messageTimer, 1000); // Set a timer to trigger after 1000ms (1 second)
}
on timer messageTimer
{
// Send a message periodically every second
output(CanMessage1); // Transmit CanMessage1 message
setTimer(messageTimer, 1000); // Reset the timer for the next period
}
In this example:
A timer named messageTimer is set to trigger every 1000 milliseconds (1 second).
When the timer triggers (on timer), it sends the message CanMessage1.
After sending the message, the timer is reset, causing the message to be sent every second.
Sending Messages at Specific Time Intervals
CAPL allows you to schedule the transmission of messages based on timing events, such as periodic signals from ECUs or timed requests.
cpp
variables
{
message CanMessage1 msg;
}
on start
{
setTimer(messageTimer, 500); // Send message every 500ms (0.5 second)
}
on timer messageTimer
{
msg.Temperature = getTemperatureSensorData(); // Set a signal value
msg.Pressure = getPressureSensorData(); // Set another signal value
output(msg); // Send the message with the updated signal values
setTimer(messageTimer, 500); // Reset timer for next message
}
In this example:
A message with signals (Temperature and Pressure) is transmitted every 500ms.
The signals are updated with sensor data and sent out via output(msg).
Signal-based Timing
Sometimes, you need to trigger actions based on signal values or signal changes over time. For instance, you might want to monitor when a signal exceeds a threshold and then trigger a message or some event.
cpp
variables
{
message CanMessage1 msg;
}
on signal Temperature // Trigger event when Temperature signal changes
{
if (Temperature > 100) // Check if temperature exceeds a threshold
{
msg.Alert = 1; // Set an alert signal
output(msg); // Send the message with the alert
}
}
In this example:
When the Temperature signal changes, it checks if the value exceeds a threshold (100).
If the threshold is exceeded, an alert signal (Alert) is set in the message and transmitted.
Using CAN Timing Functions
CAPL also offers several timing functions to manage CAN message reception and time delays effectively:
msleep(time): Sleep for time milliseconds before executing the next command.
setTimer(timer, time): Set a timer to trigger after time milliseconds.
cancelTimer(timer): Cancel a running timer.
These functions allow you to simulate real-time behaviors and delays in CAN communication. Here's an example of msleep():
cpp
on start
{
output(CanMessage1); // Send the message
msleep(1000); // Wait for 1 second
output(CanMessage2); // Send another message after 1 second delay
}
In CAPL scripting
Signals represent individual data elements in a CAN message and can be accessed or modified as part of the CAN message structure.
Message Timing is managed through setTimer(), msleep(), and other timing functions, allowing messages to be sent at specific intervals or after certain delays.
Signal-based Timing allows you to trigger events based on signal values or changes, such as generating alerts or sending data when certain thresholds are met.
These features enable effective simulation and testing of CAN systems, including real-time communication and time-dependent behavior in embedded automotive applications.
- Remember that `this.time` resolution depends on the hardware channel configuration (standard is 10 microseconds per unit, or 1 microsecond in high-precision setups).
- Be aware that timer interrupts in the Windows operating system introduce small software scheduling variations; use hardware timestamps (`this.time`) for rigorous bus jitter verification.
Select your answer for each question below to receive immediate correctness evaluation and in-depth technical rationale.
Write an `on message 0x150` handler that computes the elapsed time since the previous arrival. Assuming a nominal 20ms cycle (2000 units in 10us resolution), calculate the jitter (measured - nominal). If absolute jitter exceeds ±2ms (200 units), log a timing violation.
Verified CAPL implementation:
variables {
dword gLastMsgTime = 0;
const dword NOMINAL_CYCLE = 2000; // 20ms in 10us units
}
on message 0x150 {
if (gLastMsgTime != 0)
{
long delta = this.time - gLastMsgTime;
long jitter = delta - NOMINAL_CYCLE;
if (jitter > 200 || jitter < -200) // Exceeds +/- 2ms
{
writeLineEx(0, 2, "JITTER VIOLATION: Msg 0x150 cycle was %.2f ms (Jitter: %+.2f ms)",
delta / 100.0, jitter / 100.0);
}
}
gLastMsgTime = this.time;
}