# ECU Debugging Methodology

Reduce uncertainty in layers: host installation, analyzer identity, physical
bus, transport, diagnostic protocol, ECU state, then firmware behavior. Do not
attribute a timeout to ECU firmware before eliminating the preceding layers.

## Investigation sequence

1. Preserve the initial symptom, time, ECU software identity, bench topology,
   power state, and reproduction steps.
2. Run doctor, enumerate stable channels, validate bench configuration, timing,
   termination, mode, and analyzer firmware. Reinitialize stale physical values.
3. Start with listen/read operations. Capture raw traffic before adding cyclic
   tasks, routes, replay, or diagnostic requests.
4. Read documented identity, software version, status, voltage/temperature, and
   DTC information. Treat an NRC as protocol evidence, not a generic timeout.
5. Correlate request/response timing, resets, BUSOFF, dropped traffic, and DTCs
   with firmware logs and source paths.
6. Introduce one controlled stimulus at a time. Retain a baseline capture and
   restore state after each experiment.
7. Preserve raw frames even when using DBC decoding. Confirm the DBC network and
   ECU variant before trusting signal names or engineering values.
8. Summarize evidence as observation, timestamp, command/capture, expected,
   actual, confidence, and likely firmware subsystem.

On LIN, verify one and only one intended master supply/pull-up, both endpoint
bitrates, node roles, protected ID, DLC, checksum model, and schedule timing
before blaming a slave implementation. Capture passively first. Then issue one
authorized header or master-write, distinguish no-response from checksum/parity/error
flags, and reverse the two analyzer roles when the wiring permits it to isolate
master versus slave configuration.

Use a bounded DID or DTC read for one-off inspection. Use `message send` only for
an explicitly defined frame, hardware TX tasks for accurate periodic stimuli,
and replay only after reviewing the capture for state-changing diagnostics and
correct channel/timing/flags. Query current help before composing any command.

When the target exposes XCP, use a named A2L MEASUREMENT before falling back to
raw addresses. A synchronous read is appropriate for one state snapshot; DAQ
is appropriate for a changing internal value that must be correlated with bus
traffic. A CHARACTERISTIC write is an active ECU-state change and needs the
same explicit target, range, authorization, readback, and cleanup discipline as
other diagnostic writes.

Before UDS writes, routines, security access, DTC clearing, resets, or download,
confirm target identity and obtain authorization. Before programming, validate
artifact variant, segment map, checksum/signature, power, session/security,
bootloader preconditions, recovery path, and post-programming checks. Never
claim a firmware fix from a successful transfer without reconnecting and
re-running identity, DTC, communication, and symptom tests.

For a diagnostic workflow longer than the ECU's session timeout, use one
daemon-owned `uds present start` task instead of interleaving ad-hoc requests in
the test script. Prefer unsuppressed `3E 00` while establishing connectivity so
each `7E 00` is evidence; use `--suppress-positive-response` only when the ECU
contract permits `3E 80`. Record `uds present status --format=json` counters and
always stop the task during cleanup. A suppressed no-response is success, while
an unsuppressed timeout is a transport or ECU-state failure.

Analyzer firmware and ECU application firmware are different targets. Query
`channel enumerate --format=json`, confirm the analyzer serial or UID, then run
`device update <selector> --check`. A selector may include `/port`, but the
operation targets its parent physical device and interrupts every channel on it.
Never fall back to another analyzer when the requested identity is not found.
An analyzer update is not a generic remedy for ECU communication faults; perform
it only for a relevant published fix and with explicit authorization.

Do not confuse ECU reset, channel recovery, and analyzer reset. Try documented
channel recovery first for BUSOFF or a single-channel state problem. Use
`device reset <serial-or-uid> --format=json` only for an explicitly authorized
physical-analyzer reboot after stopping the daemon; it interrupts every channel
on that device. Record the requested UID and accept success only when BMCLI
observes both USB disappearance and same-UID re-enumeration. Revalidate the bench
profile and communication after the analyzer returns.
