Learn CAPL Script for Automotive Testing
CAPL (Communication Access Programming Language) is a C-based language that lets you control simulation, testing, and diagnostics on CAN, LIN, and FlexRay buses.
What is CAPL?
Imagine you're developing a door controller ECU. The controller needs to receive lock/unlock commands from the central system, control window movement, and send status feedback. But during development, the other ECUs aren't ready yet.
CAPL bridges this gap. It lets you create "virtual" ECUs that send test commands, simulate bus traffic, and verify your ECU's behavior — all before hardware arrives.
CAPL is event-driven: instead of a main() function that runs continuously, you define handlers that react to messages, timers, keyboard input, and more. It seamlessly integrates with CANoe/CANalyzer for comprehensive automotive testing.
Try the message interval analyzer: inspect period variation, repeated timestamps and time reversals locally, with a worked example and troubleshooting guide.
What You Can Build
Simulate Missing ECUs
Build a model with explicit message and state rules, then compare its behavior with the intended requirements.
Illustrative snippets, not validated in your configuration. Check tool version, node type and database first.
// Simulation node: demo payload, 0.1 degree per count.
variables {
msTimer tempTimer;
message 0x3A tempMsg;
byte tempTenths;
}
on start {
tempTenths = 200;
tempMsg.CAN = 1;
tempMsg.DLC = 1;
setTimer(tempTimer, 100);
}
on timer tempTimer {
tempMsg.byte(0) = tempTenths;
output(tempMsg);
if (tempTenths >= 240) tempTenths = 200;
else tempTenths++;
setTimer(tempTimer, 100);
}
Automated Test Cases
Write test cases that automatically verify ECU responses. Check timing, data values, and bus behavior without manual inspection.
Illustrative snippets, not validated in your configuration. Check tool version, node type and database first.
// Test module, single-bus example. Call from the test flow.
// Checks frame arrival, not the door's physical lock state.
testcase TC_ResponseArrival()
{
message 0x200 cmd;
long result;
cmd.CAN = 1;
cmd.DLC = 1;
cmd.byte(0) = 0x01;
output(cmd);
result = testWaitForMessage(0x201, 1000);
if (result == 1) {
testStepPass("Response", "Response frame received");
} else if (result == 0) {
testStepFail("Response", "Timeout after 1000 ms");
} else {
testStepFail("Response", "Wait error: %d", result);
}
}
Diagnostic Services
Communicate with ECUs using standardized diagnostic protocols. Read fault codes, configure parameters, and perform routines.
Illustrative snippets, not validated in your configuration. Check tool version, node type and database first.
// Tester node: replace ECU/service/parameter qualifiers
// with symbols from your configured diagnostic description.
variables {
diagRequest MyECU.ReadDTCInformation req;
}
on key 'd' {
long result;
result = diagSetParameter(req, "DTCStatusMask", 0xFF);
if (result < 0) {
write("Parameter error: %d", result);
return;
}
result = diagSendRequest(req);
write("Send request returned: %d", result);
}
on diagResponse MyECU.ReadDTCInformation {
// Inspect the response and any negative-response code.
// Receiving a response alone does not prove success.
write("Diagnostic response received");
}
Bus Analysis & Logging
Monitor bus traffic, filter specific messages, and log data for debugging and performance analysis.
Illustrative snippets, not validated in your configuration. Check tool version, node type and database first.
// Simulation node: CAN1, hexadecimal ID 0x200.
on message CAN1.0x200 {
byte cmd;
byte param;
// TIME is in 10-microsecond ticks; convert to seconds.
write("Time: %.5f s | ID: 0x%X | DLC: %d",
this.TIME / 100000.0, this.ID, this.DLC);
if (this.DLC < 2) return;
cmd = this.byte(0);
param = this.byte(1);
if (cmd == 0x05 && param > 0x10) {
write("Command matches the example filter");
}
}
Key Concepts
Event-Driven
CAPL programs wait for events (messages, timers, keys) rather than running sequentially. Each handler responds to one specific trigger.
Bus-Oriented
Built-in data types like message and signal make it natural to read and write CAN/LIN/FlexRay data directly.
C-Based Syntax
If you know C, you'll feel at home. Variables, functions, control flow — all familiar, but simpler for bus-specific tasks.
Integrated with CANoe
Available simulation, test and diagnostic features depend on the product, version, execution context and license.
Your Learning Path
Follow this step-by-step tutorial to master CAPL programming from basics to advanced topics.
Understand CAPL's role in automotive electronics, its four core application scenarios (simulation, testing, diagnostics, analysis), and event-driven programming concepts.
Install CANoe, understand the CANoe project structure (.cfg files, database, simulation nodes), and learn to use the CAPL Browser IDE for writing and compiling programs.
Master CAPL-specific data types (message, timer, msTimer), operators, control flow, and functions. Learn the differences from C language that make CAPL unique.
Learn the CAPL program lifecycle (on preStart, on start, on preStop, on stopMeasurement), master on message events, the this keyword, and output() function for sending CAN messages.
Master three essential debugging weapons: write() function for log-based debugging, breakpoints for inspecting execution state, and Watch Window for monitoring variable changes in real-time.
Learn state machine concepts and build a complete DoorModule simulation node with command response, internal state management, automatic behaviors (timers), and status feedback.
Build a bounded heartbeat wait, validate the triggering frame and distinguish timeout, interruption and payload errors.
Connect the door model and an independent observer with a shared protocol, fresh-data rules and an acceptance matrix.