Troubleshooting MCU Object Dictionary Protocol Links

Daniel Price6 min read
Other ManufacturerSerial CommunicationTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

The receiver reports a valid-looking transaction yet the destination variable stays stale, changes to the wrong value, or becomes corrupt. Follow the packet from the producer’s RAM through framing, the physical bus, deframing, dictionary lookup, and the final memcpy. The first failed observation identifies the repair branch.

Where Does the Data Path Stop?

A value change starts the path. The sender reads the registered object’s raw bytes, adds SYNC, command, object ID, length, and CRC-16 fields, then hands the frame to UART, SPI, or I2C. The receiver peripheral collects bytes, the state machine removes framing and byte stuffing, CRC validation accepts or rejects the frame, and the dictionary maps the unique 8-bit ID to a RAM address. A critical section then protects the final copy.

Checkpoint Reading to take Pass means Failure branch
Producer Registered variable and change event The application requested transmission Fix change detection or registration
Frame output Bytes at the transmit peripheral The framer emitted a packet Inspect length, stuffing, and buffer ownership
Physical link Bytes observed at the receiving peripheral The selected bus carried the transaction Repair wiring or peripheral configuration
Deframer State transitions and CRC result A complete frame reached dispatch Compare framing and CRC algorithms
Dictionary ID, declared length, and destination metadata The object has a valid mapping Reject the write and correct the schema
RAM update Destination bytes before and after the copy The object was committed Inspect concurrency and write permissions

Does the Physical Bus Deliver the Same Bytes?

Layer one first. Capture the transmitted byte sequence at the sender and the received sequence at the receiver. Compare byte count, order, and content before investigating dictionary logic. Framing cannot recover bytes lost through incorrect electrical connections, mismatched peripheral settings, or transport ownership errors.

Transport Port or address selection Traffic ownership Timing reading
UART Selected UART peripheral and pins Either endpoint may initiate when the link design permits Compare configured serial format and observe framing or overrun indications
SPI Selected SPI peripheral and chip-select path The master supplies the clock and selects the target Observe clock, selection, and data together
I2C Selected peripheral and target bus address A controller must acquire the bus and address the target Observe start, address response, data, and stop behavior

An event-driven object model does not remove SPI clock ownership or I2C addressing. A target can have new data ready while still needing a controller-initiated transaction to move it. If the byte streams match, continue at the deframer. If they differ, repair the physical or peripheral configuration and repeat the capture.

Does the Deframer Accept One Complete Frame?

Feed the captured bytes through the receive state machine one byte at a time. Record the state before and after each SYNC, stuffed byte, command, ID, length, payload byte, and CRC byte. Reset behavior matters: a malformed or truncated frame must return the machine to a known search state without dispatching a partial object.

Frame element Diagnostic Required decision
SYNC Confirm the receiver identifies the same delimiter used by the sender Reject noise and resynchronize
Command Check that the command is implemented and allowed in this direction Reject unsupported operations
8-bit ID Log the received value before lookup Dispatch only registered IDs
Length Compare declared length with collected payload bytes and object capacity Reject mismatch before copying
CRC-16 Calculate over the same fields, in the same order, at both endpoints Dispatch only on equality

Byte stuffing must be symmetrical. The transmitter escapes reserved values after forming the logical frame, and the receiver reverses that transformation before interpreting fields according to the protocol definition. Log both wire bytes and reconstructed frame bytes; comparing only one view can hide a stuffing defect. CRC-16 detects transmission corruption but does not prove that a command is authorized or that the payload type is correct.

Does the Dictionary Entry Match the Wire Object?

A raw-memory protocol needs a shared binary schema even when it avoids text parsing. For each ID, store the destination address, byte capacity, data representation, access direction, and any validation rule. Check the received length against the registered capacity before calling memcpy. An unknown ID, excessive length, disallowed command, or read-only destination must terminate dispatch without touching RAM.

Copying a raw float is safe only when both endpoints agree on its size, byte order, and object representation. A successful CRC cannot detect a semantic mismatch because it validates the transmitted bytes, not their meaning. Scaled integers can make width, signedness, resolution, and byte order explicit, but the scale and valid range must be part of the shared schema.

Observation after a valid CRC Likely mechanism Next reading
Value is byte-swapped Different byte-order convention Compare payload bytes with the destination representation
Nearby memory changes Length exceeds registered capacity or address is wrong Inspect entry address, capacity, and copy count
Value is numerically implausible Type, scaling, or floating representation mismatch Decode the same payload under the declared schema
Write affects the wrong object ID tables differ between builds Compare the registration map at both endpoints

Can the Receiver Commit the Write Safely?

The critical section must cover the smallest operation that makes the update indivisible to local readers. Disabling interrupts can prevent an interrupt handler on the same execution context from observing a partial copy, but it does not automatically coordinate a DMA engine, another execution context, or code that accesses the object without using the same synchronization rule.

Validate the command, ID, length, type metadata, range, and write permission before entering the critical section. Copy into the registered object only after every check passes. If readers require a coherent multi-byte snapshot, use the same lock around reads or publish through a staging object and an atomic ownership handoff. Never use the received ID or length directly as an unchecked array index or copy count.

CRC is an integrity check, not source authentication. On a bus where an unintended sender can inject frames, dictionary permissions and bounds checks limit damage but do not establish identity. Select authentication and replay controls from the system threat model before exposing writable control objects to an untrusted path.

How Do You Repair and Verify the Resolving Branch?

  1. Register each object with its unique 8-bit ID, address, exact byte capacity, representation, permitted command direction, and validation rule.
  2. At transmission, snapshot the object coherently, encode it according to the shared schema, construct the command, ID, length, and payload fields, calculate CRC-16, then apply byte stuffing and framing.
  3. At reception, collect a bounded frame, reverse byte stuffing, and reject incomplete frames, unsupported commands, unknown IDs, length mismatches, and CRC failures.
  4. Validate representation-specific limits before entering the critical section. Copy exactly the registered object length, then release the lock.
  5. Test one known object by recording its source bytes, complete wire frame, reconstructed payload, lookup result, and destination bytes. The source and destination representations must match byte for byte.
  6. Repeat with a reserved byte in the payload, a bad CRC, an unknown ID, a short payload, and a payload longer than the destination. Only the valid frame may change RAM.
  7. Run the update while the normal reader executes. Record repeated snapshots and confirm that no reader observes a partially updated value.

FAQ

Why does the CRC pass but the destination value look wrong?

The frame arrived intact, but the endpoints disagree about byte order, width, scaling, or floating representation. Compare the payload bytes against the registered object schema before changing framing code.

Why does an event-driven update still wait on SPI or I2C?

The object event can mark data ready, but SPI still needs master-generated clocking and I2C still needs bus acquisition and target addressing. Separate application notification from the transaction that physically transfers the frame.

Why does zero allocation not prevent memory corruption?

Static memory removes heap allocation failure, not unchecked indexing or copying. Validate the 8-bit ID, command, received length, registered capacity, and destination permission before memcpy.

How do I verify the object dictionary protocol fix?

Capture the source bytes, wire frame, deframed payload, CRC-16 result, dictionary lookup, and destination bytes for one valid transaction, then inject bad CRC, unknown-ID, short, and oversized frames. Verify that the valid transaction updates exactly one registered object and every invalid transaction leaves RAM unchanged.

Back to blog