Automotive

CAPL Programming

CAPL (CAN Access Programming Language) is the C-like scripting language built into Vector's CANoe and CANalyzer tools — the standard way to simulate ECUs that don't exist yet, automate a test sequence, or script exactly the kind of CAN and UDS exchanges covered earlier, without writing a full standalone application.

Quick reference
What it is
A C-like, event-driven scripting language built into Vector CANoe/CANalyzer for simulating, testing, and analyzing automotive bus networks.
Mental model
Not a general-purpose language — its whole structure is "when this event happens, run this code," tightly bound to the bus-simulation environment it runs inside.
Key numbers
Runs only inside CANoe/CANalyzer, never standalone; event handlers, not a linear main(), are the fundamental unit of a CAPL program.
Reach for it when
Simulating an ECU that doesn't exist yet, automating a repeatable test sequence, or scripting a diagnostic exchange for validation.

Why a dedicated scripting language?

When one ECU is under development, the rest of the vehicle's network frequently doesn't exist yet — other ECUs may not be built, available on the bench, or even finished being designed. CAPL lets an engineer simulate the missing nodes' bus behavior — sending the messages a real ECU would send, responding the way a real ECU would respond — so the ECU actually under test can be exercised realistically, entirely inside CANoe/CANalyzer, without every other real ECU physically present.

Event-driven structure

A CAPL program has no single linear main(). Instead it's a collection of independent handler blocks, each triggered by something happening on the bus or in the simulation environment:

Four kinds of events — a CAN message arriving, a timer expiring, a key press, or simulation start — are all dispatched to their matching CAPL event handler on message on timer on key on start CAPL dispatcher routes each event to its handler Matching on-handler runs may itself call output() to send a frame
Whichever event fires, the block whose declared trigger matches it runs — the rest of the script stays idle until its own trigger occurs.
on message <name>
Runs whenever a specific CAN message is received on the bus.
on timer <name>
Runs when a timer expires — the standard way to send something periodically.
on key '<char>'
Runs when a key is pressed in the CANoe UI — handy for manually triggering a test step.
on start
Runs once when the measurement/simulation starts — the usual place to arm the first timer.

A worked example: implementing the UDS +0x40 rule

This ties directly back to UDS's positive response rule — here it is, actually implemented as a CAPL event handler that answers a Read Data By Identifier request for a VIN:

variables
{
  msTimer periodicTimer;
}

on start
{
  setTimer(periodicTimer, 100); // fire every 100 ms
}

on timer periodicTimer
{
  message EngineData msg;
  msg.RPM = 2500;
  output(msg);
  setTimer(periodicTimer, 100); // re-arm for the next period
}

on message DiagRequest
{
  // SID 0x22 (Read Data By Identifier), DID 0xF190 (VIN)
  if (this.byte(0) == 0x22 && this.byte(1) == 0xF1 && this.byte(2) == 0x90)
  {
    message DiagResponse resp;
    resp.byte(0) = 0x62;  // 0x22 + 0x40 -- the UDS positive-response rule
    resp.byte(1) = 0xF1;
    resp.byte(2) = 0x90;
    // ... VIN bytes follow ...
    output(resp);
  }
}

Nothing here is exotic — it's the exact same request/response logic from the UDS page, just expressed as "when this specific message arrives, check its bytes, then send this specific response back."

Restbus simulation

Simulating the "rest of the bus" around one real device under test is one of CAPL's primary jobs — CANoe stands in for every other ECU on the network well enough that the real hardware behaves as if it were on a fully populated vehicle:

A real ECU under test shares the CAN bus with several nodes simulated by CANoe running CAPL, standing in for hardware that isn't physically present CANoe running CAPL (restbus simulation) ECU under test real hardware Node B simulated Node C simulated Node D simulated CAN bus
The ECU under test can't tell the difference between a real neighboring node and a well-written CAPL simulation of one — that indistinguishability is the entire point.

Real-world applications

Gotchas

Field notes