5.5.6 · D3Embedded Systems & Real-Time Software

Worked examples — CAN bus — frame format, arbitration, error handling — critical in aerospace

2,648 words12 min readBack to topic

This page drills the CAN bus by forcing you through every kind of situation the bus can produce: arbitration ties, arbitration losses in both directions, degenerate one-node cases, error-counter arithmetic near every threshold, the ACK collective, and a real aerospace word problem. Work each one with pencil before reading the steps.

See the parent for all definitions: CAN bus parent note.

Before anything, re-anchor the ONE electrical rule everything below rests on — the wired-AND on an open-collector bus:

Recall The single rule that decides everything

A CAN bit is either dominant (logic 0) or recessive (logic 1). The wire shows the AND of every bit driven onto it. So a single node driving 0 forces the whole bus to 0. "Dominant beats recessive." Keep this in the front of your mind for every example. What does the bus read if nodes drive 1, 1, 0 at the same instant? ::: 0 (dominant wins the wired-AND)


The scenario matrix

Every situation this topic can throw at you falls into one of these cells. The examples below are labelled with the cell(s) they cover.

Cell What varies Degenerate / limiting version Example
A. Arbitration tie then split two IDs agree for a while, then differ differ on the very first ID bit Ex 1, Ex 2
B. Direction of loss which node backs off (higher-ID loses) three nodes, staged elimination Ex 3
C. Zero / one node only one talker, or all-recessive idle nobody transmits → bus idle Ex 4
D. ACK collective some receivers pass CRC, some fail no receiver passes → ACK error Ex 5
E. Error counters — success TEC/REC climb then heal counter already at 0 can't go negative Ex 6
F. Error counters — thresholds crossing 127, 255 boundaries exactly at 127 vs 128 Ex 7
G. Real-world word problem assign IDs by urgency fire alarm must beat cabin light Ex 8
H. Exam twist data length ≠ priority; RTR/extended-ID trap equal 11-bit ID, different RTR Ex 9

Ex 1 — Cell A: two IDs that split mid-stream

Forecast: guess the winner before reading. (Hint: which number is smaller?)

Look at the two bit strings aligned, MSB (bit 10) on the left:

Figure — CAN bus — frame format, arbitration, error handling — critical in aerospace

Step 1 — Line up the bits and AND them column by column. Why this step? Arbitration happens bit-by-bit from the MSB; the bus each instant is the AND of what both nodes drive, so we must compare column by column, not compare the decimal numbers.

bit# 10 9 8 7 6 5 4 3 2 1 0
P 0 1 0 1 1 0 0 0 0 0 0
Q 0 1 0 1 1 0 1 0 0 0 0
bus 0 1 0 1 1 0 0

Step 2 — Find the first column where they disagree. Why this step? A node only loses at the moment it drives recessive (1) but reads back dominant (0). Up to that point both are happy. The first disagreement is bit 4: P drives 0, Q drives 1.

Step 3 — Apply wired-AND at bit 4. Why this step? Bus = P AND Q = 0 AND 1 = 0. Q sent 1, reads 0 → mismatch → Q backs off and becomes a receiver. P never noticed a fight and keeps transmitting.

Answer: P wins, Q loses at bit 4.

Verify: 704 < 720, and lower ID = higher priority. The winner is the smaller number — consistent. ✓ Also: the two IDs first differ in the binary place worth , and . ✓


Ex 2 — Cell A (limiting): they differ on the very FIRST bit

Forecast: how fast can arbitration be decided?

Step 1 — Compare bit 10 (the MSB) first. Why this step? This is the fastest possible arbitration — the boundary case. X drives 0 at bit 10; Y drives 1.

Step 2 — Wired-AND at bit 10. Bus = 0 AND 1 = 0. Y sent 1, reads 0 → Y loses immediately at the first ID bit.

Answer: X wins at bit 10 (arbitration decided in one bit).

Verify: 1 < 1024 → X higher priority. ✓ The very first differing bit resolves it; no bus can decide faster than one bit. ✓


Ex 3 — Cell B: three nodes, staged elimination

Forecast: guess the winner AND the order of elimination.

Step 1 — AND all three at bit 10. Why this step? The bus is the AND of all transmitters, not just two. At bit 10 all send 0 → bus 0 → nobody loses yet.

Step 2 — Reach bit 9. A sends 0, B sends 0, C sends 1. Bus = 0 AND 0 AND 1 = 0. C sent 1, reads 0 → C eliminated at bit 9. Why this step? C has a 1 in the place; A and B do not, so C's larger ID falls out first.

Step 3 — A and B continue. They agree until bit 6: A sends 0, B sends 1. Bus = 0 → B eliminated at bit 6.

Answer: winner A; elimination order C (bit 9) then B (bit 6).

Verify: IDs sorted ascending: 256 < 320 < 768 → priority order A > B > C, and the smallest survives longest. ✓ 768 has bit-9 set () → knocked out first. ✓ 320 has bit-6 set () → knocked out at bit 6. ✓


Ex 4 — Cell C: the degenerate cases (one node, or none)

Forecast: is arbitration even meaningful with one node?

Step 1 — Case (a): AND of a single driver. Why this step? With one transmitter, bus = N's bit at every instant. N always reads back exactly what it sent, never a mismatch → it "wins" trivially and sends its whole frame.

Step 2 — Case (b): all nodes idle. Why this step? An idle CAN node drives nothing, so every bit floats recessive (1). AND of all-1 = 1. An idle bus reads a steady stream of recessive bits.

Answer: (a) N always wins uncontested. (b) idle bus = recessive = logic 1.

Verify: wired-AND of one input is that input. AND over all-recessive (all 1s) = 1. ✓ This is why the recovery rule counts "11 consecutive recessive bits" as the signature of an idle bus (see Bit stuffing and clock recovery). ✓


Ex 5 — Cell D: the ACK collective (and its failure)

Forecast: how many receivers does it take to acknowledge?

Step 1 — Case (a): who overwrites the ACK slot? Why this step? Every receiver that passed CRC drives dominant (0) into the ACK slot; those that failed leave it recessive. Bus = AND of (recessive from T, 0,0,0 from the 3 passers, 1,1 from the 2 failers) = 0.

Step 2 — T reads the ACK slot. T sent recessive, reads dominant → "at least one node heard me" → frame accepted. It only takes one dominant.

Step 3 — Case (b): nobody passed. No receiver drives dominant; ACK slot stays recessive. T sent recessive, reads recessive → ACK error → T sends an error frame and retransmits.

Answer: (a) T reads dominant (0) → success even though 2 of 5 failed. (b) all-recessive → ACK error.

Verify: AND(1, 0,0,0, 1,1) = 0 → dominant. ✓ AND(1,1,1,1,1) = 1 → recessive → no acknowledgement. ✓ Contrast with CSMA-CD (Ethernet) where acknowledgement is a separate frame, not a collective bit.


Ex 6 — Cell E: error counters climb then heal

Forecast: does a witness climb fast or slow?

Step 1 — Apply the receiver rule: REC += 1 on each error. Why this step? A node merely seeing others' errors is barely punished (+1), because it isn't the offender. After 5 errors: .

Step 2 — Apply the success rule: −1 per successful frame, floored at 0. Why this step? Healing is slow but steady. After 3 successes: .

Step 3 — The degenerate floor. Why this step? If R had been at REC = 0 and received successfully, it stays 0 — counters never go negative (there is no "credit").

Answer: REC ends at 2; it cannot drop below 0.

Verify: , and keeps it . Still well under 127 → R remains Error-Active. ✓


Ex 7 — Cell F: crossing the 127 and 255 thresholds

Forecast: at which error does S flip to Error-Passive?

Step 1 — Transmitter rule: TEC += 8 per error. Why this step? The offender is punished 8× a witness so a faulty transmitter silences itself fast (fault confinement). Sequence from 120:

error # TEC state (Active if , Passive if )
start 120 Error-Active
1 128 Error-Passive ()
2 136 Error-Passive
3 144 Error-Passive
4 152 Error-Passive
5 160 Error-Passive

Step 2 — The boundary subtlety. Why this step? The threshold is strictly greater than 127. is still Active; is the first Passive value. Off-by-one traps live here.

Step 3 — Cross 255 from TEC = 250. Bus-Off. Why this step? is the hard shutdown; S removes itself from the bus entirely (recoverable later per the spec — see Mistake 3 in parent).

Answer: S flips to Error-Passive at error #1 (TEC 128); from 250, one error → TEC 258 → Bus-Off.

Verify: → Passive at the first error. ✓ is Active (boundary). ✓ → Bus-Off. ✓ (Relevant to DO-178C / DO-254 aerospace certification: a faulty LRU must isolate itself.)


Ex 8 — Cell G: real aerospace word problem

Forecast: which numeric IDs go to the fire alarm?

Step 1 — Translate urgency into ID magnitude. Why this step? Lower ID = higher priority (more leading dominant zeros). So the most urgent message gets the smallest number.

  • Engine-fire alarm → ID 1 (0b000 0000 0001)
  • Landing-gear status → ID 256 (0b001 0000 0000)
  • Cabin-lighting → ID 1024 (0b100 0000 0000)

Step 2 — Simulate simultaneous transmission. Why this step? At bit 10: fire drives 0, gear drives 0, cabin drives 1 → cabin loses at bit 10. At bit 8: fire drives 0, gear drives 1 → gear loses. Fire alarm survives every bit.

Answer: assign fire = 1, gear = 256, cabin = 1024 → fire alarm wins, always, in ≤ a few bits.

Verify: so priority strictly matches urgency. ✓ Cabin has bit 10 set () → out first. ✓ Gear has bit 8 set () → out next. ✓


Ex 9 — Cell H: exam twist — data length and RTR do NOT decide priority

Forecast: does the bigger message (more bytes) win?

Step 1 — Compare the ID fields. Why this step? Arbitration uses ID bits only; DLC and data appear far later in the frame, long after the winner is decided. So "8 bytes vs 0 bytes" is irrelevant to winning.

Step 2 — The IDs tie, so continue to the next arbitration bit: RTR. Why this step? After the 11 ID bits, the RTR bit is still in the arbitration window. D1 (data) drives RTR = 0 (dominant); D2 (remote) drives RTR = 1 (recessive).

Step 3 — Wired-AND on RTR. Bus = 0 AND 1 = 0. D2 sent 1, reads 0 → D2 loses. The data frame wins over a remote frame with the same ID.

Answer: D1 (the data frame) wins; priority is decided by ID then RTR, never by data length.

Verify: RTR dominant (0) < RTR recessive (1), so the data frame beats the same-ID remote frame. ✓ DLC = 8 vs 0 never entered the comparison → the "bigger message wins" intuition is false (parent Mistake 4). ✓