Skip to content

08 · Restbus Simulation

Testing a single ECU on a bench almost never means that ECU is alone on the bus in the real vehicle. It expects dozens of other messages from other nodes — wheel speed, ignition state, gear position — to keep arriving on schedule. Restbus simulation ("rest of bus") is the practice of using CANoe/CAPL to stand in for every node you're not physically testing, so the ECU under test believes it's in a complete, normal vehicle network.

About this module

The restbus generation and CAPL simulation patterns below are genuine, documented CANoe behavior. Nothing here was captured from a live bench — treat every snippet as a reviewed reference and verify actual cycle-time fidelity against your own hardware before trusting timing-sensitive results.

Why you need it at all

An ECU under test frequently has plausibility and timeout logic that depends on other nodes' signals arriving on schedule (Level 1's watchdog/failsafe pattern, generalized across the whole network). If you bench-test that ECU alone, with no other traffic on the bus, one of two things happens depending on the ECU's design:

  • It correctly detects the network as incomplete and enters a fault mode — which is the right behavior in real life, but means your test bench can never observe normal operation without a restbus.
  • It silently free-runs without those signals, masking a real dependency your test would otherwise never catch until vehicle integration.

Either way, a restbus simulation that faithfully reproduces the missing nodes' cycle times, startup behavior, and signal ranges is a prerequisite for almost any bench-level functional test beyond the simplest cases.

Generating a restbus from a DBC automatically

CANoe can auto-generate a baseline restbus simulation directly from a DBC's declared cycle-time attributes (Module 6):

BA_DEF_ BO_ "GenMsgCycleTime" INT 0 60000;
BA_ "GenMsgCycleTime" BO_ 256 10;   -- EngineStatus every 10ms
BA_ "GenMsgCycleTime" BO_ 512 20;   -- BrakeStatus every 20ms

CANoe reads these attributes and can generate a default network node that transmits every message at its declared cycle time with default (usually zero or start-value) signal content. This gets you a network that's present but not necessarily meaningful — the ECU under test sees traffic arriving on schedule, but every signal sitting at a default value (EngineRunning=0, VehicleSpeed=0) may itself trip preconditions your test actually needs varied.

Writing a meaningful restbus in CAPL

variables
{
  message EngineStatus engineMsg;
  message BrakeStatus brakeMsg;
  int gVehicleSpeedKph;
}

on start
{
  engineMsg.EngineRunning = 1;
  engineMsg.EngineRPM = 800;   // idle
  gVehicleSpeedKph = 0;
  setTimer(txEngine, 10);
  setTimer(txBrake, 20);
}

on timer txEngine
{
  output(engineMsg);
  setTimer(txEngine, 10);   // reschedule for continuous cycle-accurate transmission
}

on timer txBrake
{
  brakeMsg.BrakePressure = 0.0;
  output(brakeMsg);
  setTimer(txBrake, 20);
}

// Test scripts drive scenario changes through exported functions,
// not by directly touching the raw message objects
export void SetVehicleSpeed(int kph)
{
  gVehicleSpeedKph = kph;
  // ... update the relevant signal in whichever message actually carries speed
}

Exposing SetVehicleSpeed() (and similar functions for every scenario variable a test needs to control) as an exported interface — rather than having each test module poke at engineMsg fields directly — is what keeps the restbus and the test logic decoupled: the restbus owns timing fidelity, the test owns scenario intent.

Cycle-time fidelity matters more than it looks

A restbus node that transmits "roughly every 10ms" using a naive timer re-arm can drift under system load, and CANoe's own timer resolution has practical limits. For most functional tests this drift is harmless, but for anything testing timeout/failsafe logic specifically (Level 1's stale-signal watchdog), sloppy restbus timing can produce false positives — the ECU under test flags a timeout not because of a real defect but because the restbus itself missed its window. Any timeout-adjacent test result should be corroborated against a bus trace of the restbus's actual transmission times before being trusted.

Restbus vs. real other-ECU hardware: know which you're using

Restbus simulation Real other ECUs
Cost/setup Cheap, fast, scriptable Requires physical units, harnessing
Fidelity As good as the DBC + your CAPL logic Ground truth
Fault injection Trivial (Level 3 Module 6) — just send a bad value Requires actually breaking the other ECU or its wiring
Startup/sleep behavior Only as faithful as you script it Authentic, including quirks not in any spec

A mature test strategy (Level 4 Module 1) is explicit about which tests run against a restbus (fast, run constantly, catch most logic defects) versus which require real other-ECU hardware in the loop (slower, run less often, catch integration-specific surprises a simulation can't reproduce by definition).

A worked restbus-dependent test case

Field Value
Test Case ID TC-RESTBUS-004
Title ECU enters degraded mode within 500ms if EngineStatus stops arriving
Preconditions Full restbus active, ECU under test in normal operation
Steps 1. Confirm ECU in normal mode.
2. Stop the txEngine timer (simulate EngineStatus loss).
3. Wait 600ms.
4. Read ECU mode signal.
Expected result ECU mode == Degraded within 500ms of the last EngineStatus frame, per the ECU's documented timeout spec.
Notes This test is only meaningful because the restbus was providing EngineStatus reliably beforehand — verify via bus trace that EngineStatus was indeed arriving every 10ms before the timer was stopped, or a passing result proves nothing.

Cheat sheet

Concept Key point
Restbus purpose Stand in for every node not physically under test
DBC cycle-time attribute Basis for auto-generated baseline restbus
Meaningful vs. default values Auto-generated restbus often needs enrichment for real test scenarios
exported control functions Decouple restbus timing logic from test scenario logic
Timing fidelity Critical specifically for timeout/failsafe tests — verify via trace
Restbus vs. real hardware Restbus for fast/frequent logic tests; real ECUs for integration fidelity

How It Actually Works: why "roughly every 10ms" drifts, mechanically

This module's timing-fidelity warning has a precise cause worth understanding rather than just respecting. Unlike a real ECU's cyclic sender, which runs on a hardware timer inside a real-time microcontroller with true periodic interrupts, a CAPL restbus node running on a Windows-hosted CANoe measurement is scheduled by the same run-to-completion event queue introduced in Level 1 Module 5 — and setTimer(txEngine, 10) re-armed at the end of the handler measures its next 10 ms starting from whenever that handler actually finished executing, not from the timer's original nominal deadline.

If the event queue has other work pending at that instant — another node's handler mid-execution, a burst of received frames all needing processing, a write() call flushing to the log window — the runtime services all of it before returning control, and the next txEngine/txBrake cycle is pushed back by exactly that amount. Under light load this is sub-millisecond and invisible; under a busy simulation with five wheel-speed signals at 5 ms cycles plus a UDS diagnostic exchange happening concurrently (the exercise below's scenario), each node's handler execution time competes for the same single-threaded runtime, and the accumulated scheduling delay across many closely-timed cyclic senders can genuinely exceed a few milliseconds — enough to matter against a 500 ms failsafe-timeout assertion only in the aggregate, but easily enough to matter against a 50 ms wheel-speed-freeze detection window if several restbus nodes are fighting for the same runtime slice at once.

This is exactly why the worked test case insists on verifying via bus trace that EngineStatus really was arriving every 10 ms before trusting the timeout result: the trace captures the interface hardware's own timestamps (Level 1 Module 4), which reflect the true wire timing independent of whatever scheduling jitter the CAPL runtime introduced — it's the only ground truth available for confirming the restbus delivered what it was supposed to, rather than what it happened to manage under that run's particular event-queue load.

Exercise

You're testing an ABS ECU that requires VehicleSpeed, WheelSpeedFL, WheelSpeedFR, WheelSpeedRL, WheelSpeedRR, and BrakePedalPosition from four other nodes, all with different cycle times (5ms, 5ms, 5ms, 5ms, 10ms respectively).

  1. Sketch the CAPL structure (timers and exported functions only, not full implementation) you'd use to simulate these five signals with correct independent cycle times while letting a test script easily set up an "all four wheels agree, vehicle braking normally" scenario with one call.
  2. Design a fault-scenario extension: one wheel-speed signal freezes (stops updating) while the other three continue normally. Explain what this restbus needs to support to make that scenario simple to trigger from a testcase.
  3. Explain why a test asserting the ABS ECU detects the frozen-wheel fault within a specific time window is only trustworthy if you've independently verified restbus timing fidelity — referencing the worked test case above.