CAN Bus
Robust multi-node communication used heavily in automotive systems
CAN in one page
Controller Area Network (CAN) is a multi-master, message-oriented serial bus designed by Bosch for cars and presented in 1986. Every node can transmit whenever the bus is idle; collisions are resolved without losing time by bitwise arbitration on the identifier; every receiver checks every frame and destroys it for everyone with an error frame if anything is wrong; and a fault-confinement mechanism makes a broken node switch itself off. Those four ideas — priority by identifier, non-destructive arbitration, network-wide error signalling and self-disconnection — explain almost every behaviour you will ever debug.
Frames carry an identifier, not a destination address. The ID says what the data is (e.g. “engine speed”) and doubles as its priority. Every node receives every frame and decides by filtering whether it cares.
The lowest identifier wins arbitration bit by bit and continues without delay. That makes worst-case latencies analysable — the reason CAN survived 35+ years in safety-relevant systems.
Robust by design Differential wiring, bit stuffing, a 15-bit CRC, form checks, ACK and bit monitoring detect errors; error frames make data consistent network-wide; TEC/REC counters isolate faulty nodes.
Classical CAN (CAN 2.0A/B) — 0–8 bytes — up to 1 Mbit/s (typ. 125–500 kbit/s) — Body, chassis, powertrain, industry
CAN FD — 0–64 bytes — arbitration ≤ 1 Mbit/s, data phase typ. 2–5 (8) Mbit/s — Modern powertrain, ADAS, flashing, EV
CAN XL — 1–2048 bytes — data phase up to 10 Mbit/s and beyond (SIC XL) — Zonal backbones, Ethernet tunnelling How this course is organised
Sections 2–10 cover the physical and data-link layer (what every bit means). 11–14 cover timing and fault confinement, 15–18 the controller and software stack, 19–20 bus load and schedulability, 21–22 CAN FD and CAN XL, 23–27 the higher-layer protocols (ISO-TP, UDS/OBD, J1939, CANopen, DBC), and 28–33 system design, security, tools, debugging and testing. Section 34 is a multi-tab live simulator — every number in it is computed by the same code the tests verify.
Standards, versions and the OSI view
“CAN” is a family of documents. Knowing which one defines what saves hours in reviews: the frame format is in ISO 11898-1, the transceiver electrical behaviour in ISO 11898-2, and almost everything an application engineer touches (diagnostics, J1939, CANopen) is a higher-layer protocol on top.
UDS (ISO 14229), OBD (ISO 15031 / SAE J1979), J1939-71/73, CANopen (CiA 301 + profiles), AUTOSAR COM signals
ISO-TP (ISO 15765-2), J1939-21 transport (BAM / RTS-CTS), CANopen SDO segmentation
ISO 11898-1: frames, arbitration, stuffing, CRC, ACK, error handling, fault confinement (classical CAN, CAN FD, CAN XL)
ISO 11898-1: bit timing, synchronisation, bit encoding ISO 11898-2 high-speed transceivers (incl. low-power, selective wake-up, SIC); ISO 11898-3 low-speed fault tolerant; SAE J2411 single wire
Twisted pair, 120 Ω characteristic impedance, connectors (e.g. CiA 303-1, OBD J1962 pins 6/14)
1983–86 — Bosch develops CAN; presented at the SAE congress in 1986
1987 — First CAN controller chips (Intel 82526, Philips 82C200)
1991 — Bosch CAN 2.0 specification (2.0A: 11-bit IDs, 2.0B: 29-bit IDs); first series car with CAN networking (Mercedes-Benz W140)
1993 — ISO 11898 published; CAN in Automation (CiA) user group founded 1992
2001–08 — OBD-II over CAN (ISO 15765-4); mandatory in US vehicles from model year 2008
2012 — Bosch presents CAN FD; ISO 11898-1:2015 adds the ISO CAN FD format (stuff count, new CRC init)
2016 — ISO 11898-2:2016 merges high-speed, low-power and selective wake-up transceivers
2018–24 — CAN XL specified by CiA (CiA 610-1); ISO 11898-1:2024 includes CAN XL; SIC / SIC XL transceivers (CiA 601-4, 610-3)
“Non-ISO” vs “ISO” CAN FD. The original Bosch CAN FD (2012) lacked the stuff-count field and used a different CRC start value. It is not interoperable with ISO CAN FD — controllers that support both have a configuration bit for it. Always use ISO CAN FD in new designs.
Which document defines the CAN frame format and fault confinement? — ISO 11898-1 (data link layer and physical coding sub-layer). ISO 11898-2 is the high-speed transceiver.
Is ISO-TP part of CAN? — No. ISO 15765-2 is a transport protocol that runs on top of CAN to carry messages longer than one frame (e.g. UDS responses).
Physical layer: CAN_H, CAN_L and differential signalling
A high-speed CAN bus is a terminated twisted pair. The transceiver drives a dominant bit by pulling CAN_H up and CAN_L down; a recessive bit is simply “not driven” — the termination pulls both wires to the same level. Receivers only look at the difference CAN_H − CAN_L, so noise that hits both wires equally cancels out.
CAN_H — ≈ 2.5 V — ≈ 3.5 V CAN_L — ≈ 2.5 V — ≈ 1.5 V V_diff = CAN_H − CAN_L (driven) — ≈ 0 V (−0.5 … +0.05 V) — 1.5 … 3.0 V (typ. 2 V)
Receiver decision threshold — V_diff < 0.5 V → recessive — V_diff > 0.9 V → dominant
Common-mode range the receiver must tolerate — −2 V … +7 V Why “dominant wins” matters
If one node drives dominant while another leaves the line recessive, the bus is dominant. Logically the bus is a wired-AND of all transmitters (0 AND anything = 0). Arbitration, ACK and error flags are all built on this one property.
Transceiver vs controller The controller (usually inside the MCU) handles frames, CRC, stuffing and error counters and talks logic-level TXD/RXD. The transceiver (e.g. TJA1044, TCAN1042, MCP2562FD) converts TXD/RXD to the differential bus, adds protection (±40–58 V bus-pin ratings on automotive parts), a TXD dominant time-out, standby / sleep modes and wake-up.
High-speed CAN — ISO 11898-2 — up to 1 Mbit/s classical, 2–8 Mbit/s CAN FD data phase — Most common; linear bus, 120 Ω at each end
High-speed with SIC — ISO 11898-2:2024 / CiA 601-4 — CAN FD ≥ 5–8 Mbit/s — Signal-improvement: actively damps ringing after recessive edges
Low-speed fault tolerant — ISO 11898-3 — ≤ 125 kbit/s — Keeps working with one wire open or shorted; body electronics
Single-wire CAN — SAE J2411 — 33.3 kbit/s (83.3 high-speed mode) — One wire + ground; used by GM (GMLAN)
Low-power & wake-up. ISO 11898-2:2016 transceivers can sleep with microamp current and wake on a bus wake-up pattern — or, with partial-networking transceivers, only on a specific wake-up frame (selective wake-up). See AUTOSAR stack & network management.
Topology, termination and cable length
High-speed CAN is a transmission line. It must be a linear bus with the characteristic impedance (≈ 120 Ω) terminated at both physical ends; every stub and every unterminated end causes reflections that ring into the next bit.
One 120 Ω resistor at each end of the trunk — not at every node.
Power off, measure between CAN_H and CAN_L: ≈ 60 Ω = correct; ≈ 120 Ω = one terminator missing; ≈ 40 Ω = three terminators; open = both missing.
Split termination: two 60 Ω resistors with the centre tap to ground through ≈ 4.7 nF. It filters common-mode noise and improves EMC; many OEMs require it.
Termination power: under a CAN_H-to-battery fault the resistor sees large voltage — size it (e.g. 0.25–0.5 W, automotive grade).
Stubs and topology Keep stubs (drops from the trunk to a node) short — ISO guidance is ≤ 0.3 m at 1 Mbit/s; OEM specs define limits per bit rate.
Star and hybrid topologies work at low bit rates or with careful design (central termination, SIC transceivers), but make CAN FD data phases much harder.
Use twisted pair, route away from high-current switching, keep the pair together through connectors.
Ground offset between nodes eats into the −2…+7 V common-mode range — watch long buses and high-current loads.
Frame types and interframe space
Classical CAN defines four frame types. Only the data frame carries application data; the other three exist for requests, error signalling and flow control.
Data frame — The producer of a message — Carries 0–8 bytes (CAN FD: 0–64) identified by its ID
Remote frame (RTR = 1) — A consumer — Requests the data frame with the same ID. No data field, DLC = length requested. Rarely used today (CANopen discourages it); does not exist in CAN FD
Error frame — Any node that detects an error — 6-bit error flag (dominant if error active, recessive if error passive) + 8-bit recessive delimiter; destroys the current frame for everyone
Overload frame — A node that needs more time, or that sees a dominant bit in the intermission — Overload flag (6 dominant) + delimiter; delays the next frame. Modern controllers never request it themselves Interframe space (IFS)
Between frames the bus shows at least 3 recessive intermission bits. Only then may the next SOF start. An error-passive transmitter adds 8 more recessive bits (“suspend transmission”) after it has sent a frame — so it cannot hog the bus while it is suspected faulty.
After the intermission the bus is idle (recessive) until someone starts a frame. Any node with a pending frame may start with SOF; nodes that start at the same bit time arbitrate. A node that sees SOF while it has nothing to send becomes a receiver.
A data frame and a remote frame with the same ID can collide; the data frame wins because its RTR bit is dominant. Try it in the simulator's Arbitration tab.
The data frame — every field
SOF — 1 dominant — Start of frame; its falling edge hard-synchronises every node
Identifier — 11 (+18) — Message identity and priority; MSB first. 29-bit IDs = 11-bit base + 18-bit extension
RTR — 1 — 0 = data frame, 1 = remote frame. In extended frames it sits after the 18 extension bits
SRR — 1 recessive — Substitute remote request: occupies the base-format RTR position in extended frames
IDE — 1 — 0 = base format, 1 = extended format r0 / r1 — 1–2 — Reserved (sent dominant). In CAN FD the bit after IDE becomes FDF
DLC — 4 — Data length code 0–8 (values 9–15 mean 8 bytes in classical CAN; in CAN FD they encode 12…64)
Data — 0–64 — Payload, byte 0 first, each byte MSB first CRC — 15 + delimiter — CRC-15 over SOF…data (before stuffing), then a recessive delimiter
ACK — slot + delimiter — Transmitter sends recessive; any receiver that got a correct frame overwrites it dominant
EOF — 7 recessive — End of frame; intentionally violates the stuffing rule so it can never appear inside a frame
Without stuff bits a base-format data frame with n bytes is 44 + 8n bits, plus 3 intermission bits → 47 + 8n. Extended format: 67 + 8n.
Worst-case stuffing adds up to ⌊(g + 8n − 1)/4⌋ bits, with g = 34 (base) or 54 (extended): an 8-byte base frame is at most 135 bits, an 8-byte extended frame 160 bits.
At best 64 payload bits out of 111 (≈ 58 %) for base frames; 64 of 135 (≈ 47 %) in the worst case. That overhead, and the 8-byte limit, is the main motivation for CAN FD (64 bytes per frame and a faster data phase).
Why is SRR recessive? — So that a base-format data frame with the same 11 most-significant ID bits always wins arbitration against an extended frame: at that bit position the base frame sends RTR = 0 (dominant) and the extended frame SRR = 1.
What does DLC = 12 mean in classical CAN? — 8 bytes. Values 9–15 are allowed but the data field is still 8 bytes. In CAN FD, DLC 12 means 24 bytes.
Arbitration — CSMA/CR
CAN access is Carrier Sense Multiple Access with Collision Resolution. Nodes wait for bus idle, start together, and compare what they send with what they read back on every arbitration bit. A node that sends recessive (1) but reads dominant (0) has lost: it stops transmitting immediately and becomes a receiver of the winning frame — which continues unharmed. No bandwidth is wasted, and the numerically lowest ID always wins.
Engine 0x0C0 — 0 — 0 — 0 — 1 — 1 — 0 — 0 — 0 — 0 — 0 — 0 — wins
Airbag 0x0C1 — 0 — 0 — 0 — 1 — 1 — 0 — 0 — 0 — 0 — 0 — 1 ✗ — lost at ID bit 0
ABS 0x0C4 — 0 — 0 — 0 — 1 — 1 — 0 — 0 — 0 — 1 ✗ — · — · — lost at ID bit 2
Bus — 0 — 0 — 0 — 1 — 1 — 0 — 0 — 0 — 0 — 0 — 0 Rules that follow from it
Each ID must be sent by one node only (two senders of the same ID both “win” and later collide in the data field → bit errors).
Base frame beats extended frame with the same base ID (RTR 0 vs SRR 1); data frame beats remote frame with the same ID (RTR 0 vs 1).
Arbitration only works if every node sees every bit within one bit time — the origin of the bit-rate / length limit.
Priority is per message, not per node: an ECU sending both 0x080 and 0x7FF competes with different priorities.
Where priority breaks in practice Priority inversion inside a node: if the controller uses a transmit FIFO, a low-priority frame at the head of the FIFO blocks a high-priority frame behind it.
Too few transmit buffers: a buffer being aborted/reloaded misses arbitration rounds.
Non-abortable transmission of a low-priority frame delays everything (the “blocking” term B in response-time analysis).
A babbling idiot with a high-priority ID starves the whole bus — see the live simulator.
Try it: Simulator → Arbitration shows the bus level bit by bit, stuff bits inside the arbitration field and exactly where each loser drops out.
Bit stuffing
CAN uses NRZ coding — a long run of equal bits has no edges, and receivers would drift out of sync. So after five consecutive equal bits the transmitter inserts one bit of the opposite value, and every receiver removes it again. Stuffing covers SOF through the end of the CRC sequence; the fixed-form tail (delimiters, ACK, EOF) is not stuffed. data bits : 0 0 0 0 0 0 0 1 1 1 1 1 1 0 on the wire : 0 0 0 0 0 [1] 0 0 1 1 1 1 1 [0] 1 0 data bits : 0 0 0 0 0 1 1 1 1 0 on the wire : 0 0 0 0 0 [1] 1 1 1 1 [0] 0 the stuff bit [1] starts the next run: [1] + four data 1s = five, so another stuff bit follows
A stuff error is detected when six equal bits appear — the fastest error detector on the bus.
The worst case is one stuff bit per four data bits (after the first five): payload like 0x00 or 0xFF with unlucky IDs/CRCs.
Frame length depends on content, so worst-case timing analysis must assume maximum stuffing.
Error and overload flags are six equal bits on purpose: they violate stuffing, so every node notices them.
Stuffing and the CRC (a known weakness) In classical CAN the CRC is computed over the unstuffed bits. Two bit errors can create or remove a stuff bit and shift the rest of the frame, which the CRC does not always catch — reducing the effective Hamming distance. CAN FD fixes this: its CRC covers the dynamic stuff bits, a stuff count is transmitted, and the CRC field uses fixed stuff bits.
In the simulator's Frame & CRC tab, set the data to all zeros and watch the orange stuff bits appear; alternating 0x55/0xAA needs almost none.
CRC and error detection capability
The classical CAN CRC is 15 bits with generator polynomial x¹⁵ + x¹⁴ + x¹⁰ + x⁸ + x⁷ + x⁴ + x³ + 1 (0x4599), computed over SOF, arbitration, control and data field (unstuffed), with the register starting at zero. uint16_t crc15(const uint8_t *bits, int n) /* one bit per array element */ { uint16_t crc = 0; for (int i = 0; i < n; i++) { int nxt = bits[i] ^ ((crc >> 14) & 1); crc = (crc << 1) & 0x7FFF; if (nxt) crc ^= 0x4599; } return crc; /* CRC-15/CAN of "123456789" = 0x059E */ }
Bit monitoring — Transmitted bit ≠ bus bit (outside arbitration and ACK slot) — Transmitter
Stuff check — Six equal consecutive bits inside the stuffed region — All nodes
CRC check — Received CRC ≠ calculated CRC — Receivers Form check — Dominant bit in CRC delimiter, ACK delimiter, EOF (first six bits) or IFS — All nodes
ACK check — No dominant bit in the ACK slot — Transmitter How good is it?
CRC-15 has Hamming distance 6 for CAN-length frames: any combination of up to 5 randomly distributed bit errors is detected (ignoring the stuffing effect), and every burst up to 15 bits.
Together with the other mechanisms, Bosch specifies a residual error probability below message error rate × 4.7 · 10⁻¹¹.
We checked the single-bit case in this course's own receiver model: flipping every bit of 3 000 random frames (247 095 flips) — all detected (≈ 55 % by CRC, 27 % by form checks, 18 % by stuffing).
CRC-17 (poly 0x1685B) for payloads up to 16 bytes, CRC-21 (poly 0x102899) above.
The register starts with a leading 1 (1 0000…) so leading zero bits are not invisible.
The dynamic stuff bits and the stuff count are included in the CRC.
Fixed stuff bits (complement of the previous bit) are inserted before and every 4 bits in the stuff count + CRC field.
Acknowledgement
The transmitter sends the ACK slot recessive. Every node that received the frame without error — not just the intended consumer — drives the slot dominant. A dominant ACK therefore means “at least one other node received this correctly”, nothing more.
What ACK does NOT tell you That the consumer ECU got the message (any node acknowledges, even one that filters the ID away).
That the application processed it — use counters, timeouts, E2E protection or a response message for that.
Which nodes are present — for that use network management or heartbeats.
ACK error — the classic bench symptom A single node on a bus (or all others in silent/listen-only mode, or with the wrong bit rate) never gets an ACK. It retransmits forever, its TEC climbs by 8 per attempt to 128 (error passive) — and then stops rising, because an error-passive transmitter's ACK errors are not counted. So a lone node never goes bus-off, it just keeps retrying.
See it: Simulator → Live bus → “Only one node on the bus”.
Bit timing
CAN has no clock line. Each node divides its own CAN clock into time quanta (tq) and splits every bit into four segments. Getting these numbers right — the same bit rate and (nearly) the same sample point on every node — is the single most common configuration task.
SYNC_SEG — Edges are expected here — always 1 tq PROP_SEG — Compensates the round-trip delay: 2 × (cable + transceiver + controller delays) — 1…n tq
PHASE_SEG1 — Can be lengthened by resynchronisation — 1…n tq
PHASE_SEG2 — Can be shortened by resynchronisation; bits are sampled at its start — ≥ SJW and ≥ the information processing time (1–2 tq, controller specific)
SJW — Max. amount PS1/PS2 may be adjusted per resync — 1 … min(4, PS2) classical; larger in CAN FD tq = BRP / f_CAN bit time = (1 + PROP_SEG + PHASE_SEG1 + PHASE_SEG2) · tq = N · tq bit rate = f_CAN / (BRP · N) sample point = (1 + PROP_SEG + PHASE_SEG1) / N Most controllers merge PROP_SEG + PHASE_SEG1 into one register field "TSEG1" and store BRP-1, TSEG1-1, TSEG2-1, SJW-1.
Worked example — 80 MHz clock, 500 kbit/s, 87.5 % 80 MHz / 500 kbit/s = 160 clocks per bit. With BRP = 2 → N = 80 tq (12.5 ns each): TSEG1 = 69, TSEG2 = 10 → sample point (1 + 69)/80 = 87.5 %, SJW = 10.
For a 40 m bus with 150 ns node delay the round trip is 2 · (40 · 5 + 150) = 700 ns = 56 tq at BRP 1 — the propagation segment fits inside TSEG1.
Allowed oscillator tolerance for that setting: ±0.485 % — trivial for a crystal.
Choosing the sample point Late (80–87.5 %): more room for propagation delay → longer buses. The usual automotive / CiA choice up to 500 kbit/s.
1 Mbit/s: 75–80 % is typical because the bit is short.
CAN FD data phase: 70–80 %, and transmitter delay compensation (TDC) instead of a propagation segment.
All nodes should use nearly the same sample point — mismatches reduce the tolerance to clock differences and ringing.
Prefer the smallest BRP (most tq per bit): finer placement and larger SJW.
Oscillator tolerance (Bosch bit-timing note): Δf ≤ min(PS1, PS2) / (2 · (13 · N − PS2)) and Δf ≤ SJW / (20 · N). The simulator's Bit timing tab evaluates both, together with the propagation budget, for every valid prescaler.
Synchronisation
Two mechanisms keep all nodes aligned to the transmitter's bits despite clock tolerance and delays.
On the SOF edge (the first recessive-to-dominant edge after bus idle or intermission), every node restarts its bit time: the edge is by definition in SYNC_SEG. This removes any accumulated phase error at the start of each frame.
Inside a frame, every recessive-to-dominant edge that falls outside SYNC_SEG is a phase error e. If the edge is late (e > 0) PHASE_SEG1 is lengthened, if it is early PHASE_SEG2 is shortened — by at most SJW. ISO 11898-1:2015 uses only recessive-to-dominant edges for synchronisation.
Why stuffing and timing belong together Stuffing guarantees an edge at least every 6 bits, and a recessive-to-dominant edge at least every 10 bits (the worst case the tolerance formula assumes). Between two resynchronisations the accumulated drift must stay below SJW — which is where the SJW / (20 · N) condition comes from. The 13 · N condition covers the longest stretch without resynchronisation: the edge at an error flag after up to 13 bits.
A node's crystal is 0.8 % off and the network uses N = 8 tq, SJW = 1. Will it work? — Probably not: SJW/(20·N) = 1/160 = 0.625 % < 0.8 %. Increase N and SJW, or fix the clock.
Why do dominant bits dominate synchronisation? — Because only a dominant level is actively driven; recessive-to-dominant edges are sharp and well defined, while dominant-to-recessive edges depend on the termination and can ring.
Error detection, error frames and overload frames
When a node detects an error it immediately starts an error flag. An error-active node sends six dominant bits — this deliberately violates the stuffing rule, so every other node detects a stuff (or form) error and sends its own flag. The flags overlap (“superposition”, 6–12 bits in total) and are followed by an 8-bit recessive error delimiter. The frame is discarded by everyone and the transmitter retransmits automatically.
Bit error — Transmitter (bit read back ≠ bit sent). Not in arbitration, not in ACK slot, not while sending a passive error flag — next bit
Stuff error — Any node: 6 equal bits in the stuffed region — next bit
CRC error — Receivers: calculated ≠ received CRC — after the ACK delimiter (so the ACK can still be seen as a separate problem)
Form error — Any node: dominant bit in a fixed-form field (CRC delimiter, ACK delimiter, EOF, IFS) — next bit
ACK error — Transmitter: ACK slot stayed recessive — next bit (the ACK delimiter)
Consistency: why destroy the frame for everyone?
If one receiver saw a corrupted frame and others did not, some ECUs would act on data others never received. The error frame makes the outcome all-or-nothing: every node discards the frame, and the retransmission reaches all of them. (There is a corner case around the last EOF bit — which is why receivers accept a frame one bit earlier than transmitters.)
An overload flag (6 dominant) followed by an 8-bit delimiter delays the next data frame. It is sent when a dominant bit is detected in the first two intermission bits (or, historically, when a slow receiver needs time). At most two consecutive overload frames may be generated. Overload frames do not change error counters and do not cause retransmission.
Try the error injection: in Simulator → Frame & CRC, click any bit to flip it and see whether receivers detect a stuff, CRC or form error.
Fault confinement: TEC, REC, error-passive and bus-off
A node that keeps causing errors must not take the network down. Every controller keeps a transmit error counter (TEC) and a receive error counter (REC). Errors raise them much faster than successes lower them, so a node with a persistent local fault drifts into error-passive and finally switches itself off (bus-off).
Receiver detects an error (except a bit error while sending an active error flag or overload flag) — REC + 1
Receiver sees a dominant bit as the first bit after sending its error flag — REC + 8
Transmitter sends an error flag — TEC + 8 (exceptions below)
Exception 1: error-passive transmitter detects an ACK error and sees no dominant bit while sending its passive error flag — TEC unchanged
Exception 2: stuff error during arbitration on a stuff bit that should have been recessive but was sent recessive and monitored dominant — TEC unchanged
Bit error while sending an active error flag or overload flag — TEC + 8 (transmitter) / REC + 8 (receiver)
More than 7 consecutive dominant bits after an error/overload flag (14 after an active flag, 8 after a passive one, and each further 8) — + 8
Successful transmission (ACK received, no error until end of EOF) — TEC − 1 (if > 0)
Successful reception — REC − 1 if 1…127; if > 127 it is set to a value between 119 and 127
Bus-off recovery — after 128 occurrences of 11 consecutive recessive bits → error active, TEC = REC = 0 What the states mean for behaviour
Error active: normal; signals errors with 6 dominant bits (destroys the frame for everyone).
Error warning (TEC or REC ≥ 96): not an ISO state, but most controllers raise an interrupt — the early sign of trouble.
Error passive: still communicates, but signals errors with 6 recessive bits (it can no longer destroy other nodes' frames) and waits 8 extra bits after transmitting.
Bus-off: transmitter and ACK are off. The node waits for 128 × 11 recessive bits; many controllers also require the software to request recovery.
Recovery policy is a design decision Automatic hardware recovery gets a faulty node back after ≈ 1 400 bit times — on a quiet 500 kbit/s bus about 3 ms — and it will immediately fail again. AUTOSAR CanSM uses a fast first retry and slower retries afterwards, reports a DTC, and informs the application. In the live simulator compare “Hardware auto” with “Software, 100 ms” in the faulty-transceiver scenario: with hardware recovery the faulty BMS cycles through bus-off about every 50 ms and the healthy receivers' REC climbs close to 127; with a 100 ms wait there are three times fewer bus-offs.
A node transmits 20 frames, each hit by a bit error, then 100 successful frames. What is its TEC? — 20 × 8 = 160 (error passive after the 16th), then −100 → 60 → error active again.
Why can a node that is alone on the bus not reach bus-off? — Each attempt is an ACK error: +8 until TEC = 128 (error passive). From then on exception 1 applies — ACK errors of an error-passive transmitter do not increase TEC — so it stays at 128 and keeps retrying.
Which node usually goes bus-off when a CAN_H wire breaks near one ECU? — The ECU cut off from the others: it transmits without ACK or with bit errors, while the rest of the bus keeps working.
CAN controller architecture
The controller turns frames into bits. Software never sees stuff bits, CRCs or error flags — it sees mailboxes, FIFOs, filters, counters and interrupts. How those are organised decides whether your priorities survive inside the ECU.
Writes TX buffers, reads RX FIFOs, handles interrupts and bus-off
TX buffers (dedicated, FIFO or priority queue), RX FIFOs, dedicated RX buffers, TX event FIFO, timestamps
Mask/code or list/range filters route IDs to FIFOs or reject them in hardware
Arbitration, stuffing, CRC, ACK, error detection, TEC/REC, state machine
Prescaler, segments, synchronisation, CAN FD data-phase timing and TDC To the transceiver Transmit buffer strategies
Priority queue by ID (e.g. M_CAN TX queue, bxCAN with “priority by identifier”): the controller always offers the lowest ID — correct CAN semantics.
FIFO: offers frames in write order — causes priority inversion within the node.
Dedicated buffers per message: deterministic and common in AUTOSAR configurations; a new instance overwrites an unsent one (the simulator counts those as overruns).
Abort: a pending low-priority frame can be aborted to make room — but a frame already on the bus cannot be interrupted.
Initialisation / configuration: bit timing and filters can only be changed here.
Listen-only / silent / bus monitoring: receives but never sends ACK or error flags — for loggers and bus analysers.
Loopback (internal / external): self-test without a bus.
Restricted operation (CAN FD controllers): receive and ACK but no error flags; used during automatic bit-rate detection.
Sleep / power-down with wake-up on bus activity.
bxCAN — STM32F1/F4 etc. — Classical CAN, 3 TX mailboxes (priority by ID or FIFO), 2 RX FIFOs × 3, 14/28 filter banks
M_CAN / FDCAN — Bosch IP in STM32G4/H7, Microchip SAM, TI, NXP… — CAN FD, shared message RAM, TX FIFO/queue, RX FIFO 0/1, TX event FIFO, TDC
FlexCAN — NXP i.MX, S32K, Kinetis — Mailbox based, optional RX FIFO, CAN FD on newer parts
MCP2517FD / MCP2518FD — External SPI controller — Adds CAN FD to MCUs without it
Acceptance filtering
Every frame reaches every controller; filters decide which ones are stored and interrupt the CPU. Good filtering is the difference between a CPU that idles and one that spends 30 % of its time throwing away frames. accept if (received_id & mask) == (filter_id & mask) mask bit = 1 → that ID bit must match, mask bit = 0 → don't care filter_id = 0x100, mask = 0x700 → accepts 0x100 … 0x1FF (only the top 3 bits compared) filter_id = 0x0C0, mask = 0x7FF → accepts exactly 0x0C0 filter_id = 0x000, mask = 0x000 → accepts everything Filter types you will meet
Mask mode: one ID + mask per bank (ranges that align to powers of two).
List mode: exact IDs, 2–4 per bank.
Range filters (M_CAN): from…to.
Dual ID: two exact IDs.
Filters can also check IDE (11- vs 29-bit) and RTR, and route matches to different FIFOs (e.g. diagnostics to FIFO 1).
Allocate ID ranges so that each ECU's inputs can be matched with few masks.
Always include the IDE bit in the mask, or 29-bit frames can match 11-bit filters.
Keep a dedicated FIFO/buffer for diagnostics and network management so heavy periodic traffic cannot overflow them.
Software filtering is the fallback when hardware filters run out — measure its CPU cost at worst-case bus load.
The SocketCAN example in the next section uses exactly these two filters (0x0C0 exact and 0x100–0x1FF) and shows which frames get through.
Driver software and SocketCAN
On an MCU the CAN driver configures the controller, moves frames between message RAM and software queues, and handles errors. On Linux, SocketCAN exposes CAN interfaces as network devices you use with ordinary sockets.
MCU driver checklist Enable clocks, configure TX/RX pins (pin mux) and the transceiver's standby/enable pins.
Enter initialisation mode; set bit timing (nominal and, for FD, data phase + TDC).
Configure filters and FIFO/buffer allocation.
Enable interrupts: RX FIFO new message/full/lost, TX complete, error warning, error passive, bus-off.
Leave initialisation mode; wait until the controller has synchronised (11 recessive bits).
TX: find a free buffer, write ID/DLC/data, request transmission — or queue in software if none is free.
RX ISR: drain the FIFO completely, timestamp, push to a lock-free ring buffer; process in a task.
Bus-off: notify, apply the recovery policy, record a DTC.
SocketCAN from the shell (can-utils) 0x3E0 is outside both filters and the 29-bit frame does not match because the masks include CAN_EFF_FLAG — exactly the IDE tip from the filtering section. CAN FD frames arrive only because the receiving socket enabled CAN_RAW_FD_FRAMES (and the interface MTU is 72).
AUTOSAR communication stack and network management
In production ECUs, application code rarely touches frames. It reads and writes signals; AUTOSAR basic software packs them into PDUs, schedules them, routes them and handles the bus state.
Rte_Write / Rte_Read of signals such as VehicleSpeed Signal ↔ I-PDU packing, transmission modes (cyclic / on change / mixed), deadline monitoring, update bits, signal groups UDS diagnostics (via PduR ↔ CanTp)
Routes PDUs between Com, Dcm, CanTp, gateways ISO 15765-2 segmentation for long diagnostic messages
Hardware abstraction: PDU ↔ CAN ID, controller/transceiver modes, TX buffering
Network management, bus-off recovery state machine, communication modes Controller and transceiver drivers Network management (AUTOSAR CanNm)
Every node that needs the bus sends periodic NM messages (typically in an ID range, e.g. 0x500–0x57F) with its node ID and a control bit vector.
States: Bus-Sleep → Repeat Message → Normal Operation → Ready Sleep → Prepare Bus-Sleep → Bus-Sleep.
The network goes to sleep only when no node requests it any more: coordinated shutdown without a master.
Partial networking: selective-wake transceivers (ISO 11898-2:2016) stay asleep unless a configured wake-up frame appears, so only the needed ECUs wake — saving quiescent current in EVs.
Data integrity above CAN: E2E protection CAN's CRC protects the frame on the wire — not the path through gateways, buffers and software.
AUTOSAR E2E profiles add a CRC over the data plus a data ID, an alive/sequence counter and a timeout check in the receiver.
Detects repeated, lost, delayed, inserted, masqueraded and corrupted messages — required for ISO 26262 safety signals.
Security (authenticity) is separate: SecOC — see the security section.
Periodic — Sent every cycle time — Continuous values: speed, temperatures
Direct / on change — Sent when a signal with TRIGGERED property changes (with minimum delay) — Events: button pressed, door opened
Mixed — Periodic + immediate on change (optionally N repetitions) — Status that must react quickly but also be refreshed None — Only on request — Rarely used
Bus load
Bus load is the fraction of time the bus is busy. Because arbitration is priority-based, high load does not break high-priority messages first — it silently delays the lowest priorities until they miss deadlines or overrun. load = Σ ( frame_bits_i · bit_time / period_i ) 8-byte base frame, worst case 135 bits @ 500 kbit/s = 270 µs sent every 10 ms → 270 µs / 10 ms = 2.7 % of the bus
0x0C0 EngineData, 8 B — 10 ms — 270 µs — 2.70 % 0x0F0 GearStatus, 4 B — 20 ms — 190 µs — 0.95 %
0x1A0 WheelSpeeds, 8 B — 20 ms — 270 µs — 1.35 % 0x2B0 BatteryStatus, 8 B — 50 ms — 270 µs — 0.54 %
0x3A0 EngineTemps, 8 B — 100 ms — 270 µs — 0.27 % 0x3E0 ClusterStatus, 2 B — 200 ms — 150 µs — 0.08 % Total — 5.88 % (23.5 % at 125 kbit/s)
Many OEMs specify ≤ 50–70 % average load, leaving margin for event bursts, error frames and future messages.
Look at peaks, not averages: at start-up and on events many messages align.
Use offsets between periodic messages of one ECU to spread load.
Error frames and retransmissions consume load too — at a 10⁻⁴ bit error rate about 1.3 % of 8-byte frames are hit, each costing an error frame plus a full retransmission.
Throughput numbers worth remembering 500 kbit/s, 8-byte base frames: ≈ 3 700 (worst stuffing) to 4 500 frames/s → ≈ 30–36 kB/s of payload.
CAN FD 64 bytes at 500 kbit/s / 2 Mbit/s: ≈ 333 µs per frame → ≈ 190 kB/s.
CAN FD 64 bytes without bit-rate switch at 500 kbit/s: ≈ 1.16 ms per frame.
Worst-case response time analysis
Because arbitration is priority-based and non-preemptive, the worst-case latency of every message can be calculated before the car is built. The classic analysis (Tindell, 1994) turned out to be optimistic in some cases; the corrected version by Davis, Burns, Bril and Lukkien (2007) is what tools use today. C_m = worst-case transmission time (maximum stuffing, incl. 3-bit IFS) B_m = max C of lower-priority messages (one of them may just have started) t_m = busy period: t = B_m + Σ_{k ∈ hep(m)} ⌈(t + J_k) / T_k⌉ · C_k Q_m = ⌈(t_m + J_m) / T_m⌉ instances to check for q = 0 … Q_m − 1: w(q) = B_m + q·C_m + Σ_{k ∈ hp(m)} ⌈(w(q) + J_k + τ_bit) / T_k⌉ · C_k R(q) = J_m + w(q) − q·T_m + C_m R_m = max_q R(q) schedulable if R_m ≤ deadline (usually the period)
0x0C0 EngineData (10 ms) — 0.270 ms — 0.540 ms — 2.160 ms 0x0F0 GearStatus (20 ms) — 0.190 ms — 0.730 ms — 2.920 ms
0x1A0 WheelSpeeds (20 ms) — 0.270 ms — 1.000 ms — 4.000 ms 0x2B0 BatteryStatus (50 ms) — 0.270 ms — 1.270 ms — 5.080 ms
0x3A0 EngineTemps (100 ms) — 0.270 ms — 1.420 ms — 5.680 ms 0x3E0 ClusterStatus (200 ms) — 0.150 ms — 1.420 ms — 5.680 ms
The counter-example that changed the analysis Three messages with C = 1 ms and periods 2.5, 3.5, 3.5 ms. The original analysis gives the lowest-priority message R = 3 ms; the real worst case is 3.5 ms, because its second instance in the busy period is delayed more than the first. The revised analysis checks every instance in the busy period — our implementation returns 2, 3 and 3.5 ms.
What the analysis assumes Every node always offers its highest-priority pending frame (no FIFO priority inversion).
Queuing jitter J is known (task jitter, gateway delays).
No errors — add an error model (e.g. k error frames + retransmissions in any window) for fault-tolerant designs.
Worst-case stuffing; real frames are shorter, so measurements must come out lower.
The live simulator shows the analytic R_m next to the observed maximum latency for every message. In our tests (3 s runs at ×1 and ×8 rates, 500 kbit/s) no observed latency exceeded its analytic bound — and in the “overloaded bus” scenario the analysis correctly reports missed deadlines.
CAN FD
CAN FD (Flexible Data-rate) keeps arbitration exactly as in classical CAN — so the bus length limit stays — but after arbitration it can switch to a faster bit rate and carry up to 64 bytes. The result is 3–6× more real throughput on the same wiring.
FDF (was EDL) — Recessive = FD frame. In classical frames this position is the dominant r0 bit
RRS — Remote request substitution, always dominant — CAN FD has no remote frames
BRS — Bit-rate switch: 1 = the rest of the frame (up to the CRC delimiter) uses the data bit rate. The switch happens at the sample point of BRS
ESI — Error state indicator: 1 = the transmitter is error passive. Lets receivers see a sick node's state in every frame
DLC — 0–8 as usual; 9…15 → 12, 16, 20, 24, 32, 48, 64 bytes (lengths in between are padded)
Stuff count — Number of dynamic stuff bits mod 8 in Gray code + even parity bit (ISO CAN FD only)
CRC — CRC-17 up to 16 bytes, CRC-21 above; starts with a leading 1; covers the stuff bits; fixed stuff bits every 4 bits
Throughput (computed by the simulator's encoder) Classical 8 bytes at 500 kbit/s: 112 bits ≈ 224 µs → 8 payload bytes.
CAN FD 64 bytes, 500 kbit/s / 2 Mbit/s: 29 nominal + 550 data-phase bits ≈ 333 µs → 64 bytes.
Same frame at 500 kbit/s / 5 Mbit/s: ≈ 168 µs.
64 bytes without BRS at 500 kbit/s: ≈ 1.16 ms — still better per byte than eight classical frames, but BRS is where the gain is.
Transmitter delay compensation (TDC): at 2+ Mbit/s the transceiver loop delay is longer than a bit. The transmitter checks its own bits at a secondary sample point = measured delay + offset.
Ringing on stubs and star points limits the data rate — SIC transceivers (CiA 601-4) help reach 5–8 Mbit/s.
Every node needs the same data-phase timing; tq should be as short as possible (small BRP), and the data-phase prescaler is usually set equal to the nominal one.
Transceivers must be specified for CAN FD (symmetry and loop delay at 2/5 Mbit/s).
Mixing classical and FD nodes. A classical-only controller cannot follow an FD frame: after the recessive FDF bit it interprets the fast data phase as garbage and sends error frames, destroying every FD frame. Either all nodes on a bus are FD-capable, or classical nodes must be “FD-tolerant” (ignore FD frames) or be put behind an FD-shield / partial-networking transceiver. Classical frames, however, are valid on an FD bus — FD controllers send and receive both.
You need to send 20 bytes in CAN FD. Which DLC and how many bytes go on the bus? — DLC 11 → 20 bytes, no padding. For 17 bytes you would also use DLC 11 and pad 3 bytes (commonly 0xCC or 0x00).
Why is the arbitration phase still slow? — All nodes must see every arbitration bit within one bit time across the whole bus (round-trip delay). Only one transmitter remains after arbitration, so the data phase can be faster.
CAN XL
CAN XL (CiA 610-1, included in ISO 11898-1:2024) extends the idea further: arbitration as in CAN, then a data phase of 10 Mbit/s and more carrying up to 2048 bytes — enough for a full Ethernet frame. It is designed as a cost-effective backbone for zonal architectures, complementary to 10BASE-T1S Automotive Ethernet.
Priority ID (11 bit) — Only used for arbitration — CAN XL separates priority from content addressing; no 29-bit IDs XLF — Marks a CAN XL frame (after FDF)
ADS / DAS — Arbitration-to-data and data-to-arbitration sequences where the bit rate and, with SIC XL transceivers, the transceiver mode switch
SDT — SDU type — What the payload is: e.g. native CAN XL content, a tunnelled classical/FD frame, or an IEEE 802.3 Ethernet frame
SEC — Payload is protected by the CADsec security layer (CiA 613-2)
DLC (11 bit) — Payload length − 1 (1…2048 bytes, byte granular)
SBC + PCRC — Stuff-bit count and a 13-bit preface CRC protecting the header
VCID — Virtual CAN network ID — several logical networks on one cable (like VLANs)
AF (32 bit) — Acceptance field: content or address information for filtering, independent of the priority
FCRC (32 bit) — Frame CRC over the whole frame With SIC XL transceivers (CiA 610-3) the transceiver switches during the data phase from arbitration mode to a fast mode with push-pull, level-based signalling — allowing 10–20 Mbit/s on the same twisted pair. The data phase uses fixed stuff bits (every 10 bits) so the bit count is deterministic.
Classical CAN: sensors, actuators, body functions (low cost).
CAN FD: today's powertrain/chassis and fast ECU flashing.
CAN XL: zone controller backbones, Ethernet tunnelling (layer-2), large payloads with deterministic priority — co-existing with FD nodes on the same bus.
ISO-TP (ISO 15765-2) — messages longer than one frame
Diagnostics needs messages of hundreds or thousands of bytes (DTC lists, flash blocks). ISO-TP segments them into CAN frames and adds flow control, using the first byte(s) of each frame as the Protocol Control Information (PCI).
Single Frame (SF) — 0 — 0L dd dd … — L = length 1–7. CAN FD: 00 LL + up to 62 bytes
First Frame (FF) — 1 — 1L LL dd dd dd dd dd dd — 12-bit length (≤ 4095); escape 10 00 + 32-bit length for larger
Consecutive Frame (CF) — 2 — 2N dd dd dd dd dd dd dd — N = sequence number 1…F, 0, 1… (7 data bytes each)
Flow Control (FC) — 3 — 3S BS ST — S: 0 = continue, 1 = wait, 2 = overflow; BS = block size; ST = STmin Flow control parameters
BS (block size): number of CFs before the next FC; 0 = no further FC.
STmin: minimum gap between CFs. 0x00–0x7F = 0–127 ms, 0xF1–0xF9 = 100–900 µs.
Timeouts: N_Bs (sender waiting for FC) and N_Cr (receiver waiting for next CF), typically 1000 ms; a wait FC (0x31) restarts N_Bs.
Normal: one CAN ID per direction (OBD: request 0x7E0–0x7E7, response +8, functional 0x7DF).
Normal fixed (29-bit): 0x18DA<TA><SA> physical, 0x18DB<TA><SA> functional (e.g. 0x18DB33F1).
Extended: first data byte carries the target address (one byte less payload).
Mixed: address extension byte for sub-networks.
Padding: fill unused bytes (often 0xAA, 0x55, 0xCC) or use the shortest DLC — OEM specific.
Read the trace: the 3-byte request fits a Single Frame (03 22 F1 90). The 20-byte response starts with 10 14 (FF, length 0x014 = 20), the tester answers 30 04 05 (continue, BS 4, STmin 5 ms), and two CFs 21…, 22… follow. In the 100-byte transfer a new FC appears after every 4 CFs, and the last CF carries only the 3 remaining bytes because no padding was configured. The simulator's ISO-TP tab produces exactly the same frames.
Diagnostics over CAN: UDS and OBD-II
UDS (ISO 14229) is a request/response protocol: the tester sends a service ID (SID) and parameters, the ECU answers with SID + 0x40 or a negative response 7F SID NRC. On CAN it rides on ISO-TP (ISO 15765-2 / -3); OBD-II emission diagnostics uses the same transport (ISO 15765-4).
10 — DiagnosticSessionControl — 10 03 → extended session (50 03 + P2/P2* timings) 11 — ECUReset — 11 01 hard reset
14 — ClearDiagnosticInformation — 14 FF FF FF all DTCs 19 — ReadDTCInformation — 19 02 09 → DTCs with status mask 0x09
22 — ReadDataByIdentifier — 22 F1 90 → VIN 27 / 29 — SecurityAccess / Authentication — seed-key or certificate-based unlock before protected services
2E — WriteDataByIdentifier — 2E F1 98 … (e.g. repair shop code)
31 — RoutineControl — 31 01 FF 00 → start erase memory routine
34 / 36 / 37 — RequestDownload / TransferData / RequestTransferExit — flash programming sequence
3E — TesterPresent — 3E 80 keeps a non-default session alive, no response
85 / 28 — ControlDTCSetting / CommunicationControl — stop DTC logging and normal traffic during flashing Negative responses worth knowing
7F 22 31 requestOutOfRange (unknown DID) 7F 27 35 invalidKey, 7F 27 36 exceededNumberOfAttempts
7F xx 7F serviceNotSupportedInActiveSession 7F xx 78 responsePending — the ECU needs more time; the tester extends its timeout from P2 (typ. 50 ms) to P2* (typ. 5 s) 7F xx 33 securityAccessDenied OBD-II on CAN in one example
For sessions, security access, DTC status bits and the complete flashing flow, open the dedicated UDS lesson .
SAE J1939 — trucks, buses, agriculture, off-highway
J1939 is a complete higher-layer protocol on 29-bit CAN (250 kbit/s per J1939-11, 500 kbit/s per J1939-14). Instead of arbitrary IDs, the identifier is structured into priority, a Parameter Group Number (PGN) that says what the data is, and the source address of the sender. bits 28–26 priority (0 = highest, 3 control, 6 typical info) bit 25 EDP (extended data page) bit 24 DP (data page) bits 23–16 PF (PDU format) PF < 240 → PDU1: PS = destination address bits 15–8 PS (PDU specific) PF ≥ 240 → PDU2: PS = group extension (broadcast) bits 7–0 SA (source address) 0x0CF00400 → priority 3, PGN 0xF004 = 61444 (EEC1, engine speed), SA 0x00 (engine #1) 0x18FEF100 → priority 6, PGN 0xFEF1 = 65265 (CCVS1, vehicle speed), SA 0x00 Parameters: PGN and SPN
A PGN defines a message (length, rate, content); each value inside is an SPN (Suspect Parameter Number) with resolution, offset and range.
Example: EEC1 (PGN 61444) byte 4–5 = engine speed, 0.125 rpm/bit (SPN 190).
Special values: 0xFF… = not available, 0xFE… = error indicator.
Requests: PGN 59904 (0xEA00) asks any node for a PGN.
Address claiming (J1939-81) Every ECU has a 64-bit NAME (identity, function, manufacturer…) and claims a source address by broadcasting PGN 60928 (0xEE00).
If two ECUs claim the same address, the one with the lower NAME keeps it; the other picks another address (if arbitrary-address capable) or reports “cannot claim” (SA 254).
SA 255 is the global (broadcast) destination; 254 is the null address.
Transport protocol (J1939-21) for 9…1785 bytes TP.CM (PGN 60416) announces or negotiates the transfer; TP.DT (PGN 60160) carries 7 bytes + sequence number per packet (up to 255 packets).
BAM (broadcast announce): no flow control, 50–200 ms between packets.
RTS/CTS (peer-to-peer): the receiver grants packets with CTS and confirms with End-of-Message ACK; Abort ends it.
DM1 (PGN 65226) — active DTCs as SPN + FMI + occurrence count — often uses BAM when several DTCs are active.
Decode and build identifiers in Simulator → J1939 & CANopen.
CANopen (CiA 301)
CANopen is the dominant CAN higher layer in industrial automation, medical devices, rail and many embedded products. Its heart is the object dictionary: every parameter and process value of a device has a 16-bit index and 8-bit sub-index.
0x000 — NMT — Network management commands from the master: 01 start, 02 stop, 80 pre-operational, 81 reset node, 82 reset communication
0x080 — SYNC — Synchronisation for cyclic PDOs 0x080 + node — EMCY — Emergency error messages 0x100 — TIME — Time stamp
0x180 / 0x280 / 0x380 / 0x480 + node — TPDO1–4 — Process data sent by the device (up to 8 bytes, no protocol overhead)
0x200 / 0x300 / 0x400 / 0x500 + node — RPDO1–4 — Process data received by the device
0x580 + node / 0x600 + node — SDO server→client / client→server — Confirmed access to any object-dictionary entry (configuration)
0x700 + node — NMT error control — Heartbeat (state byte) and boot-up message (0x00)
Initialisation → sends boot-up → Pre-operational (SDO allowed, no PDOs) → Operational (PDOs active) ↔ Stopped (only NMT and heartbeat).
Heartbeat state byte: 0x00 boot-up, 0x04 stopped, 0x05 operational, 0x7F pre-operational.
SDO in one exchange 0x1000–0x1FFF — Communication profile: device type (0x1000), error register (0x1001), heartbeat (0x1017), identity (0x1018), PDO communication (0x1400/0x1800) and mapping (0x1600/0x1A00) 0x2000–0x5FFF — Manufacturer-specific
0x6000–0x9FFF — Device profile (e.g. CiA 402 drives, CiA 401 I/O)
DBC files and signal encoding
A CAN matrix — which ECU sends which message, and where every signal sits in it — is usually exchanged as a DBC file (Vector format, de-facto standard) or as AUTOSAR ARXML. Tools use it to decode traces and generate code. BU_: EngineECU ABS Transmission BMS Cluster BO_ 192 EngineData: 8 EngineECU SG_ EngineTorque : 16|8@1+ (1,-125) [-125|130] "%" Transmission,Cluster SG_ EngineSpeed : 24|16@1+ (0.125,0) [0|8191.875] "rpm" Transmission,Cluster SG_ ThrottlePos : 40|8@1+ (0.4,0) [0|102] "%" Transmission BO_ 688 BatteryStatus: 8 BMS SG_ PackVoltage : 7|16@0+ (0.01,0) [0|655.35] "V" Cluster SG_ PackCurrent : 23|16@0- (0.1,0) [-3276.8|3276.7] "A" Cluster SG_ StateOfCharge : 39|8@0+ (0.5,0) [0|127.5] "%" Cluster BA_ "GenMsgCycleTime" BO_ 192 10; VAL_ 240 CurrentGear 0 "Neutral" 1 "First" 2 "Second" 15 "Invalid";
24|16 — Start bit | length. Intel: start = LSB position. Motorola: start = MSB position (DBC numbering: bit = byte·8 + bit-in-byte)
@1 / @0 — Byte order: 1 = Intel (little endian), 0 = Motorola (big endian)
+ / - — Unsigned / signed (two's complement) (0.125,0) — physical = raw · factor + offset
[min|max] "unit" — Physical range and unit receivers — Nodes that consume the signal
BO_ 192 — Message ID in decimal (0xC0). 29-bit IDs are written with bit 31 set: 0x80000000 | id
Intel vs Motorola — the #1 source of wrong values A 16-bit value 0x1234 packed Intel from bit 0 gives bytes 34 12; packed Motorola from start bit 7 gives 12 34. A Motorola signal runs from its MSB down to bit 0 of that byte and continues at bit 7 of the next byte (the “sawtooth”). Use the simulator's DBC signals tab to see the bit matrix for any definition.
Multiplexing and good practice SG_ Mux M: 0|8@1+ … and SG_ CellV m3: 8|16@1+ … — the multiplexor value selects which signal set the rest of the frame contains (e.g. cell voltages 1–96 in 24 frames).
Reserve invalid / not-available values (e.g. all ones) and document them in VAL_ tables.
Put an alive counter and CRC (E2E) into safety-relevant messages.
Keep one source of truth (DBC/ARXML) and generate code from it — hand-written bit masks drift.
The signal positions in this DBC are the ones the live simulator actually uses: its “Decoded signals” panel decodes the trace with exactly these definitions.
Gateways and vehicle network architecture
A modern car has 5–15 CAN/CAN FD buses plus LIN, FlexRay and Ethernet. Gateways connect them, route selected messages and signals, isolate faults and enforce security boundaries — and every hop adds latency that must fit the end-to-end timing budget.
Domain architecture (classic) One bus per function domain: powertrain, chassis, body, infotainment, ADAS, diagnostics.
A central gateway routes between domains and to the OBD connector.
Simple ownership, but long harnesses and many ECUs.
Zonal architecture (current) Zone controllers collect local sensors/actuators (via CAN, CAN FD, LIN) by location and connect to central computers over Ethernet (or CAN XL / 10BASE-T1S).
Fewer, shorter wires; software moves to central compute.
CAN stays at the edge; gateways translate between CAN signals/PDUs and Ethernet (SOME/IP, or CAN-over-Ethernet tunnelling).
Frame (PDU) routing — Whole frame, possibly with a new ID — Fast (µs–sub-ms), often in hardware or low-level software
Signal routing / gatewaying — Individual signals repacked into other messages — Flexible but adds processing and timing jitter
Diagnostic routing — ISO-TP messages between the OBD port and internal buses — Must respect ISO-TP timing on both sides; often security-gated
Tunnelling — CAN frames inside Ethernet (e.g. AUTOSAR PDU routing, IEEE 1722 ACF) — Used for backbones and logging
Gateway delay is a jitter term J in response-time analysis on the destination bus. A frame received at the end of the gateway's cycle is forwarded one cycle later — include that worst case.
Security on CAN (defensive design)
Classical CAN has no sender authentication and no encryption: any node can send any identifier, and every node sees all traffic. CAN was designed for closed networks. Once a vehicle has external connectivity (telematics, infotainment, OBD dongles), the architecture must assume that some node might be compromised — and protect what matters.
Segmentation: put safety-critical ECUs on buses separate from externally connected ones; the gateway only forwards what each side needs (allow-lists per direction).
Diagnostic access control: UDS SecurityAccess (0x27) or certificate-based Authentication (0x29) before writing, routines or flashing; limit attempts; gate diagnostics by vehicle state (e.g. standstill).
Secure boot and signed software updates, so an ECU only runs authentic firmware.
Message authentication (SecOC) for critical commands.
Intrusion detection (IDS) with logging and reporting to a security operations process.
AUTOSAR SecOC in short The sender appends a truncated MAC (e.g. CMAC-AES-128, truncated to 24–64 bits) and a truncated freshness value (counter or time) to the PDU.
The receiver rebuilds the full freshness value, recomputes the MAC with the shared key and rejects mismatches or stale values (replay protection).
Costs bandwidth — CAN FD's 64 bytes make room; classical 8-byte frames often cannot spare the bytes.
Keys must be provisioned and stored securely (HSM / secure element) — key management is the hard part.
What a CAN IDS looks at Timing: periodic messages suddenly arriving faster or with a changed period.
Specification: IDs a bus should never carry, DLCs that do not match the DBC, values out of range.
Correlation: signals that must agree (wheel speeds vs vehicle speed).
Bus health: unusual error-frame rates or a node repeatedly entering bus-off.
Regulations make this mandatory: UNECE R155 (cyber-security management system) and R156 (software updates) apply to new vehicle types, with ISO/SAE 21434 as the engineering standard. CAN XL adds CADsec, a security layer built into the protocol.
Tools, logging and trace formats
Vector CANoe / CANalyzer — Industry standard for analysis, rest-bus simulation, test automation (CAPL), DBC/ARXML databases
PEAK PCAN-View, Kvaser CanKing, Intrepid Vehicle Spy — Interfaces with trace, send and log software
Linux SocketCAN + can-utils — candump, cansend, cangen, canbusload, isotpsend/isotprecv, isotpdump — scripting with python-can and cantools
Oscilloscope with CAN decode — Physical layer: levels, edges, ringing, reflections, ground offset, bit timing
Logic analyser — TXD/RXD at the controller: timing, sample point issues, transceiver behaviour
Data loggers — Long-term fleet logging to MDF4 / BLF with triggers
ASC — Text (Vector) — Human-readable trace: timestamp, channel, ID, direction, DLC, data
BLF — Binary (Vector) — Compact, the usual CANoe log format MF4 (ASAM MDF 4) — Binary, standard — Measurement data incl. bus logging; widely supported by analysis tools candump log — Text (SocketCAN) — (1700000000.123456) can0 123#DEADBEEF — replayable with canplayer
PCAP / PCAPNG — Binary — Wireshark can dissect SocketCAN captures Reading a trace efficiently
Load the DBC so you see signals, not bytes.
Look at statistics first: frame rate per ID, period jitter, error frames, bus load.
Filter to one ECU's transmit IDs to check its cycle times and startup behaviour.
Correlate error frames with events (relay switching, motor start, cranking).
To test one ECU on the bench, a tool simulates all the other ECUs' messages (with correct cycle times, counters and CRCs) — otherwise the ECU under test sets timeout DTCs or refuses to run. The DBC + E2E configuration drives the simulation.
Debugging playbook
Most CAN problems fall into a handful of patterns. Work from the physical layer up.
No communication at all, transmitter TEC rises to 128 and stays — No ACK: only one node, others off / in listen-only / wrong bit rate — Is a second node powered and in normal mode with the same bit rate?
Bursts of error frames, all nodes' REC rising — Wrong bit rate or sample point on one node, bad termination, noise — Measure 60 Ω; compare bit timing registers of all nodes; scope the bus
One ECU goes bus-off repeatedly — Its transceiver/wiring (open CAN_H or CAN_L at that ECU), wrong timing on that node, local ground problem — TEC of that node vs others; swap harness/transceiver; check supply and ground
Works on the bench, fails in the car — Harness length/stubs, ground offset, EMC from motors or DC/DC converters — Scope at several points; common-mode voltage; ringing after edges
Errors only at high load or specific IDs — Worst-case stuffing + marginal timing; oscillator tolerance — Frames with many 0x00/0xFF; clock accuracy; increase SJW
Low-priority messages late or missing — Bus overload, FIFO priority inversion inside a node, babbling node — Bus load and per-ID periods; transmit buffer strategy
CAN FD frames destroyed, classical fine — Classical-only node on the bus, data-phase timing/TDC, ringing — Remove nodes one by one; lower data rate; check TDC configuration
Values decoded wrong — Intel/Motorola mix-up, wrong start bit, signedness, factor/offset — Decode by hand with the DBC; compare with the ECU's own log Measurements with the power off
CAN_H–CAN_L: ≈ 60 Ω. 120 Ω → one terminator missing; ≈ 40 Ω → one too many.
CAN_H or CAN_L to ground and to battery: should be high impedance (kΩ range and above), not a short.
Measurements with the power on (idle bus) CAN_H ≈ CAN_L ≈ 2.5 V (recessive). CAN_H stuck near 3.5 V or V_diff constantly high → a node is holding the bus dominant (TXD stuck low; transceivers have a dominant time-out for this).
With a scope: dominant V_diff ≈ 1.5–3 V, clean edges, no ringing extending into the sample point.
Reproduce the classics safely in Simulator → Live bus: lone node (ACK error), faulty transceiver (bus-off cycle), babbling idiot, noisy harness and overload.
Testing and validation
ISO 16845-1: conformance test plan for CAN controllers (data link layer), ISO 16845-2 for transceivers.
Silicon vendors certify their controllers; ECU projects rely on that and test the integration.
ECU / network tests (OEM specifications) Physical layer: bit timing on the real harness, sample point, termination, ground offset, EMC.
Communication: cycle times, start-up time to first message, timeouts, signal default values, bus-off recovery timing, NM sleep/wake.
Diagnostics: UDS services, DTC setting/clearing, flashing incl. interruption and recovery.
Robustness: bus load up to 100 %, error frames injected, short circuits of CAN_H/CAN_L to ground and battery, supply dips during cranking.
Rest-bus simulation — Run one ECU as if the whole vehicle were there
Hardware-in-the-loop (HIL) — Real ECU + simulated plant + simulated network; automated regression
Fault injection (disturbance tools) — Flip bits, corrupt CRCs, force error frames, stretch bits — verify error handling and recovery
Stress / load tests — Generate worst-case bus load and check deadlines of the lowest-priority messages
Static analysis of the CAN matrix — Unique IDs per sender, response-time analysis, DLC/signal overlaps, E2E coverage
Interview questions
Short, precise answers — the way experienced interviewers expect them.
Why is CAN called message-based rather than address-based? — Frames carry an identifier describing the content, not a destination. All nodes receive every frame and filter by ID; the ID also sets the priority.
What happens when two nodes start transmitting simultaneously? — Bitwise arbitration on the identifier: dominant (0) overwrites recessive (1). A node that sends 1 and reads 0 stops and becomes a receiver. The lowest ID continues without any delay or corruption.
Why do you need 120 Ω at both ends? — To terminate the transmission line with its characteristic impedance and prevent reflections, and to discharge the bus back to recessive quickly. Two in parallel give 60 Ω.
What is bit stuffing and why is it needed? — After five equal bits the transmitter inserts one opposite bit so there are enough edges for resynchronisation; six equal bits signal an error. It covers SOF to the CRC sequence.
List the five error types. — Bit, stuff, CRC, form and ACK errors.
Explain TEC and REC and the three error states. — Counters increased by errors (+8 for transmit errors, +1 for most receive errors) and decreased by successes. >127 → error passive (recessive error flags, suspend transmission); TEC > 255 → bus-off (node off the bus until 128 × 11 recessive bits).
Can a single node on the bus go bus-off? — No. Its ACK errors raise TEC to 128, then the ACK exception for error-passive transmitters stops further increments.
What is the sample point and how would you choose it? — The position within the bit where the level is read, as a percentage of the bit time. Typically 87.5 % up to 500 kbit/s, 75–80 % at 1 Mbit/s, identical on all nodes; it must leave room for the propagation delay.
What is SJW? — Synchronisation jump width: the maximum number of time quanta by which a resynchronisation may lengthen phase segment 1 or shorten phase segment 2.
Differences between CAN and CAN FD? — FD: up to 64 bytes, optional faster data phase (BRS), ESI bit, no remote frames, CRC-17/21 with stuff count and fixed stuff bits. Arbitration identical.
What does a dominant ACK prove? — Only that at least one node received the frame without error — not that the intended consumer processed it.
How do you compute bus load? — Sum of (frame length in bits × bit time ÷ period) over all messages, using worst-case stuffing for design margins.
What is priority inversion in CAN and how do you avoid it? — A low-priority frame blocks a higher-priority one inside the same node (FIFO TX buffer) — use priority-ordered TX queues or dedicated buffers. On the bus, a started low-priority frame always blocks for one frame time (non-preemptive).
How does ISO-TP send 20 bytes? — First Frame (1L LL + 6 bytes) → Flow Control from the receiver (30 BS ST) → Consecutive Frames 21, 22 … with 7 bytes each.
Why can't classical-only nodes share a bus with CAN FD traffic? — They cannot decode the FD format and data phase, detect errors and send error frames that destroy every FD frame.
What is a babbling idiot and how do you protect against it? — A node that continuously transmits (often a high-priority ID), starving the bus. Protection: bus guardian logic, TXD dominant time-out in transceivers, watchdogs that reset the ECU, and gateway isolation.
Intel vs Motorola byte order in DBC? — Intel (@1): start bit is the LSB, bytes ascending. Motorola (@0): start bit is the MSB, continuing at bit 7 of the next byte.
How do you secure CAN? — Segmentation with filtering gateways, diagnostic authentication, secure boot/updates, SecOC (MAC + freshness) for critical messages, and intrusion detection.