FCEV · Big Red · production program · vehicle E/E & embedded software architecture

A fuel-cell truck, architected from a blank platform

Big Red is a Class 6 fuel-cell electric commercial truck on a Kenworth T280 chassis: 7+ ECUs from different suppliers, six CAN buses, one supervisory controller, and me as the sole embedded software engineer. This page is about the shape of that system — how it was layered, where the network was cut, what was treated as the source of truth — and how it compares with a zonal design of the same truck.

Hierarchical supervisory control Gateway-segmented CAN · J1939 Simulink · Stateflow · Embedded Coder System Composer HARA · DFMEA · FTA Raptor · OpenECU · XCP · UDS
Role sole embedded software engineer, architecture through flash Employer Fontaine Modification (Marmon) Team led up to 4 concurrently, 7 across the program
7+
ECUs integrated into one supervisory architecture
85% → 60%
average CAN bus load after re-segmentation
6 h → 10 min
source-address fault isolation using the architecture drawing
3 wk / unit
component rework removed by generating diagrams from interface data

01 — Architectural style

Hierarchical supervisory control over supplier subsystem ECUs

The fuel cell, battery, eAxle, brakes and HVAC each arrived with their own controller and their own firmware. That fixed the style before any drawing was made: the vehicle's behaviour had to live in one supervisory layer that commands subsystem ECUs through their published CAN interfaces and never reaches around them. Gateways sit between the layers so that each subsystem's traffic stays on its own segment.

Commands flow down as setpoints and enables. State and faults flow up. Nothing talks sideways across subsystems except through the supervisor, which is what keeps a change in one supplier's firmware from quietly altering another subsystem's behaviour.

logical view — layers and message directionanimated — commands down, status up
L3 · SUPERVISORY L2 · GATEWAYS L1 · SUBSYSTEM ECUs L0 · SENSORS · ACTUATORS · HV CONTACTORS backbone Supervisory controller RCM112 · Simulink → generated C Gateway AGCM48 Gateway BGCM48 Fuel cellBallard ctrl H2CUhydrogen BatteryBMS eAxleLinamar ctrl BrakesBendix ABS ThermalHVAC · pumps command · setpoint · enable state · fault · diagnostic
Logical view, simplified. The controlled drawing set places every node on one of six CAN buses — five at 500 kbps plus the chassis OEM's K-CAN at 250 kbps — with part numbers, suppliers and termination; that detail is not reproduced here. Node-to-segment grouping above is illustrative.
Why "supervisory" and not "central"

The supervisor owns vehicle modes, sequencing and arbitration — which subsystem is enabled, in what order, under what faults. It does not own the fuel cell's air loop or the eAxle's current loop; those stay inside the supplier's ECU where the supplier's calibration and warranty live. That split is what made it possible to integrate hardware nobody on the team could reflash to our own code.

02 — Decision: cut the network

One busy segment, or segments with a gateway between them

As subsystems came online, average load on the shared CAN segment climbed past 85%. At that level, arbitration delays low-priority frames, error recovery has no headroom, and every new node makes timing worse for everyone. Gateways were added to split the network, and the bus was re-segmented around them so that high-rate subsystem traffic stays local and only the frames the supervisor needs cross over.

bus segmentation — before and afterinteractive — auto-plays, or choose a state
SupervisoryFuel cell BatteryThermal eAxleBrakes DC/DCOBC ONE SEGMENT · EVERY FRAME SEEN BY EVERY NODE Gateway filters SEGMENT ASEGMENT B AVERAGE BUS LOAD over 85% 60%
Load figures are the measured before/after averages. Traffic density and which ECU sits on which segment are drawn to show the mechanism, not the actual frame schedule. The single red token in the segmented view is a frame the gateway is configured to forward.
ADR-01 · Segment CAN around added gatewaysaccepted · implemented · verified in-vehicle
Context
Shared segment above 85% average load as subsystems were integrated; supplier ECUs could not be made to transmit less.
Decision
Add GCM48 gateways and re-segment the bus around them. Keep high-rate subsystem traffic local; forward only what the supervisor consumes.
Rejected
Raise the bit rate — not every supplier node supported it. Cut transmit rates — firmware not ours. A second flat bus with no gateway — splits load but leaves no single place to filter or police traffic.
Consequences
Average load down to 60%. Gateway routing tables became an interface artifact that must be versioned with the DBC. Architecture documentation and the Simulink model were updated, rebuilt, reflashed and the load re-measured.

03 — Interfaces as data

The pinout is the source of truth; diagrams are generated from it

A multi-thousand-wire truck changes constantly during build. Hand-drawn architecture diagrams fall behind within days, and a stale diagram is worse than none because people trust it. So the interface definition was made data — one pinout workbook with a fixed schema — and the drawings were derived from it, never edited directly.

interface data → checks → generated viewsanimated — one revision propagating
PIPELINE Pinout sheetsingle source of truth Integrity checksduplicate · splice GeneratorsExcel → masks · script System Composer modelcomponent masks CAN topology diagramVisio · source addresses rev edited UML · INTERFACE DATA MODEL Subsystem name Device partserialinstancelocationtemperature Pin name · numbertypeAWG · colourvoltagedestination LOC-Device-Connector-Position CanPin polaritybusNumbersourceAddress 1* 1*
Schema and naming convention as designed. The integrity stage exists because the modelling tool resolved splices but not duplicates — a two-stage check was added rather than trusting the import. CAN pins carry bus and source address so the network view can be generated from the same rows as the harness.
ADR-02 · Generate architecture views from interface dataaccepted · in daily use
Context
Diagrams maintained by hand drifted from the harness; rework followed from building against stale drawings.
Decision
One pinout workbook, fixed three-level schema, naming convention enforced. Drawings and System Composer masks are outputs. The workflow, data model and reference document were mine; an LLM was used only to generate script syntax against that specification.
Rejected
Model-first in an MBSE tool — the electrical team lived in spreadsheets; a model they would not edit would drift the other way. Keep drawing by hand, add review — adds cost without removing the cause.
Consequences
Component rework cut by 3 weeks per unit. The CAN topology stayed current through design changes, which paid off directly in section 04.

04 — The architecture drawing earning its keep

A source-address collision, found in ten minutes

After a regenerative braking resistor (brake chopper) was integrated, the eAxle started misbehaving. Tracing it by hand — supplier documents, schematics, a multi-thousand-wire pinout — was estimated at six hours. With a source-address-annotated topology already in hand, it took ten minutes to see that two nodes on the same segment claimed the same J1939 source address.

collision → diagnosis → re-architecture → regenerated viewanimated — 14 s
shared segment · 500 kbps CAN4 · 250 kbps eAxle ctrlSA = n other nodes Brake chopperSA = n ANNOTATED TOPOLOGY eAxle ctrl · shared · SA n brake chopper · shared · SA n brake chopper · CAN4 · 250k generated from pinout rows 1 · TWO NODES, ONE SOURCE ADDRESS, ONE SEGMENT 2 · READ THE DRAWING, NOT THE HARNESS — 6 H → 10 MIN 3 · REFLASH 500 → 250 KBPS, MIGRATE TO CAN4 4 · SCRIPT REGENERATES THE TOPOLOGY — TEAM STAYS ALIGNED
The actual address value is replaced with n. Build → payoff → fix → maintain: the drawing tool from section 03 isolated the fault, the fix was an architectural move rather than a firmware patch, and the same tool updated the shared reference afterwards.

05 — Runtime view

Multi-rate scheduling inside the supervisor

A supervisory model mixes fast loops, slower mode logic, and CAN traffic that arrives whenever the subsystem ECU decides to send it. Treating all of that as one rate either starves the fast loop or wastes the processor. The supervisor was partitioned by rate, with explicit rate-transition boundaries so data crossing between rates is never read half-written.

process view — rates, interrupts, transitions, watchdoganimated — 8 s sweep
base-rate task slower task CAN Rx interrupt→ function-call subsys watchdog · overrun rate transition
Structure as implemented on the supervisory controller: Rate Transition blocks for multi-rate data integrity, function-call subsystems triggered by CAN Rx interrupts, watchdog and task-overrun monitoring. Rates and arrival times are drawn schematically.

06 — Safety as an architectural property

Removing a single point of failure the HARA found

A hazard analysis on the supervisory thermal system surfaced dead code and a structural problem: one cab ambient air temperature sensor sat on a path where its failure could take down the whole thermal system. No amount of testing the existing logic fixes that — the architecture needed a second path.

fault path — before and after the fallbackanimated — 10 s
Cab ambient tempsensor Fault detectionrange · plausibility Fallback algorithmdegraded, still controlling Thermal supervisorypumps · fans · valves NORMAL PATH SENSOR LOST · SYSTEM STAYS UP
Detection logic simplified. The finding and the backup/fallback algorithm are real; the dead code the HARA surfaced was removed in the same change.

Energy isolation boundary

Defined which loads stay live under lock-out/tag-out — only the equalizer and DC-DC, with the whole truck below 60 V — specified a double-pole switch to kill both 12 V and 24 V, and flagged that telematics stops logging when it trips.

DFMEA on an architecture gap

Found an electrical-architecture gap that made hydrogen refuelling impossible without an added switch. Led the DFMEA, built the AND/OR fault tree, guided the EE to the fix and updated supervisory controls.

Fleet-safe flashing

Six ECUs updated in one session — two supervisory controllers, VCU, H2CU, two gateways — each on a distinct XCP address so no unit could receive another's build.

07 — Contrast

What we built, next to how it would look zonal

Big Red was partitioned by subsystem: each subsystem — fuel cell, hydrogen, battery, eAxle, brakes, thermal — kept its own controller, and the network was cut along those lines. It was not a zonal architecture. The useful question for a zonal program is what the same truck would look like organised by location instead, and what that would have cost and bought.

As built · by subsystem

Supervisory controller over subsystem ECUs

Grouped by what each ECU does. Supplier ECUs integrated as delivered; wiring runs from each subsystem to wherever its partners are.

Redesign · by location

Zone controllers + central compute

Grouped by where things are on the chassis. Short wiring to the nearest zone, behaviour centralised in software.

On Big RedAs built · by subsystemZonal redesign
Supplier ECUs (fuel cell, eAxle, ABS, BMS, HVAC)integrated as deliveredkept as smart nodes on zone-local CAN, or re-implemented — needs their software
Network loadover 85% on a shared segment, fixed to 60% with gatewaysEthernet backbone between zones; CAN runs stay short
Harness lengthlong runs along the frame between subsystemsshort stubs to the nearest zone
Fault and change containmentper subsystem, gateway filtersper zone, but central compute is shared
Software updatessix ECUs flashed individuallyone coordinated release
Cost for a handful of prototype truckslowhigh — new zone hardware and software
Why subsystem was right here, and when zonal wins

With fixed supplier ECUs, a donor chassis and a few trucks, organising by subsystem was the cheapest way to a working vehicle. At fleet volume, with software owned in-house, harness cost and whole-vehicle updates dominate and the answer flips toward zonal. What carries over either way: interface data as the source of truth, explicit rate and fault boundaries, and a network that is measured rather than assumed.

Scope, stated plainly: the subsystem architecture is the one I built and measured. The zonal version is design analysis — it was never built.

Zonal explained step by step, with Big Red redrawn on its chassis →