Solution strategy¶
arc42 §5 — the toolchain’s shape is the consequence of nine architectural decisions captured below. The structure of the decisions mirrors Solution strategy so the rationale chain from ESI to EDS is explicit and visible.
Context. Future CANopen support via ... (ADR_0073) foresaw the OD-IR lift but left it open. Two paths were possible: (a) lift now as part of the CANopen codegen round, (b) ship CANopen with a duplicated OD IR and lift later. Decision. Lift now. Consequences. ✅ Parser cost amortised over both fieldbuses. ✅ Closes Future CANopen support via ... (ADR_0073). ✅ No future breaking-change cycle to lift later. ❌ One mechanical refactor on existing Device-driver codegen toolc... (FEAT_0050) crates. The lift is low-risk because parser and IR were already decoupled (per Parser separated from codeg... (ADR_0070)). |
Context. Possible additions to a shared OD crate include
built-in serde derives, Decision. Consequences. ✅ Smallest possible blast radius for both parsers. ✅ Stable surface — adding a derive is additive. ❌ Two consumers (parsers) carry their own serde wiring; acceptable since the serde frontends are different anyway (XML vs INI). |
Context. Device-driver codegen toolc... (FEAT_0050) is already shipped. Two options
for compatibility: (a) break the API and bump major version,
(b) re-export the lifted types from Decision. Re-export. Consequences. ✅ Existing Device-driver codegen toolc... (FEAT_0050) consumers
compile source-unchanged. ✅ No major version bump needed. ❌
Two paths exist for the same type. Acceptable — the canonical
path is documented ( |
Context. Two reasonable INI crates exist in the Rust
ecosystem with passive (no-I/O) APIs: Decision. Treat them as interchangeable behind a serde-derive
façade. Consequences. ✅ The IR is decoupled from the INI tokeniser choice. ✅ Backend can be flipped without IR churn. ❌ The choice is deferred to the planning phase; the spec does not fix it. |
Context. When two devices’ PDOs carry the same bit-len +
data-type tuple list but different field names (e.g.
Decision. Structural dedup only — names are not part of the dedup key (per Common PDO entry types dedu... (REQ_0733)). The EtherCAT side made the same call implicitly; this ADR captures it explicitly for both fieldbuses going forward. Consequences. ✅ Higher dedup hit rate across devices that share a CiA profile (e.g. CiA 402 servo drives). ✅ Smaller generated artefacts. ❌ Two devices’ identical-shaped PDO structs may have field names from one device only. Acceptable — downstream code accesses by position via typed getter, not by the EDS-side string. |
Context. CANopen permits Decision. Skip. Typed PDO structs carry only real-payload
fields; bit offsets are threaded through generated Consequences. ✅ Cleaner API surface. ✅ No temptation for
callers to write padding fields. ❌ |
Context. Outbound TPDO frames need a payload buffer. Three
options: Decision. Consequences. ✅ No per-frame allocation. ✅ Sound across
embedded targets without a global allocator. ❌ CAN-FD’s
64-byte payload would need |
Context. The trait surface must distinguish hot-path frame
plumbing ( Decision. Mixed. Consequences. ✅ No runtime dependency leaks into the hot
path. ✅ Same posture as |
Context. The verifier needs a dump format to compare EDS against. Four options: CSV (lossy on hex / type info), custom binary (opaque to git review), YAML (heavier dep), JSON (inspectable, diff-able, schema-tag-able). Decision. JSON with explicit Consequences. ✅ Inspectable in git diffs. ✅ Easy to
produce from any tool (Python |