Requirements¶
System-level requirements. The spec is organised under three peer top-level features:
PLC runtime heart on iceoryx2 (FEAT_0010) “PLC runtime heart on iceoryx2” — taktora-executor framed as the runtime heart of a soft-real-time PLC. See Soft-RT PLC runtime heart.
Connector framework (FEAT_0030) “Connector framework” — the general-purpose framework for bridging taktora-executor applications to external protocols. See Connector framework.
Bounded global allocator (FEAT_0040) “Bounded global allocator” — workspace infrastructure providing a static, pre-allocated, fixed-block
#[global_allocator]for taktora binaries that require compile-time guarantees on memory usage. See Bounded global allocator.Device-driver codegen toolc... (FEAT_0050) “Device-driver codegen toolchain” — build-time layered crates that translate EtherCAT ESI XML into strongly-typed Rust device drivers, consumed by
taktora-connector-ethercatand any other ethercrab user. See Device-driver codegen.CANopen device-driver codeg... (FEAT_0060) “CANopen device-driver codegen toolchain” — build-time layered crates that translate CANopen EDS (CiA 306) files into strongly-typed Rust device drivers, with a shared
fieldbus-od-coreOD IR co-owned by the EtherCAT toolchain. See CANopen device-driver codegen.
Each req directive :satisfies: one feat parent; each
capability-cluster feat :satisfies: its top-level umbrella feature.
Requirements at a glance¶
ID |
Title |
Status |
Satisfies |
|---|---|---|---|
Configurable scan period |
open |
||
One execution per scan period |
open |
||
Scan-cycle execution observability |
open |
||
Subscriber-triggered ingestion |
open |
||
Publisher-driven emission |
open |
||
Zero-copy IPC transport |
open |
||
Notification-drop visibility |
open |
||
Sequential chain execution |
open |
||
Parallel DAG execution |
open |
||
Abort propagation |
open |
||
Conditional inclusion |
open |
||
Subscriber deadline detection |
open |
||
Per-execute timing visibility |
open |
||
Core-affinity assignment |
open |
||
SCHED_FIFO priority on Linux |
open |
||
Signal-driven shutdown |
open |
||
Programmatic shutdown wakeup |
open |
||
No heap allocation in dispatch |
implemented |
||
Statically-sized task pool |
open |
||
Pre-allocated error slot |
open |
||
Wait-free completion signalling |
open |
||
Per-task overrun fault transition |
open |
||
Executor-wide overrun fault transition |
open |
||
Fault-handler item dispatch |
open |
||
Fault state observability |
open |
||
Mode lifecycle |
open |
||
Mode transition triggers |
open |
||
Per-mode task gating |
open |
||
Mode change observability |
open |
||
Process-restart persistence |
open |
||
Memory-mapped backing |
open |
||
Crash-atomic checkpoints |
open |
||
Recovery status reporting |
open |
||
Per-task latency percentiles |
draft |
||
Per-task maximum jitter |
draft |
||
Per-task overrun counter |
draft |
||
Statistics query API |
draft |
||
Allocation-free telemetry update |
draft |
||
Documented worst-case jitter |
draft |
||
Cyclictest-style benchmark harness |
draft |
||
Documented reproducer procedure |
draft |
||
Harness consumes runtime telemetry |
draft |
||
Adapter-driven I/O |
open |
||
Out-of-tree driver crates |
open |
||
Protocol-neutral runtime |
open |
||
ConnectorEnvelope is a POD type |
open |
||
Per-channel max payload size |
open |
||
Sequence number monotonically increasing |
open |
||
Timestamp recorded at send |
open |
||
Correlation id is a passive carrier |
open |
||
Zero-copy publish via iceoryx2 loan |
open |
||
One iceoryx2 service per channel direction |
open |
||
PayloadCodec trait |
open |
||
Codec is a generic parameter on connectors |
open |
||
JsonCodec is the default codec |
open |
||
Codec encode error variant |
open |
||
Codec decode error variant |
open |
||
Connector trait |
open |
||
ChannelDescriptor carries typed routing |
open |
||
Routing is a marker trait with bounds |
open |
||
create_writer / create_reader return concrete handles |
open |
||
Connector ships its own routing struct |
open |
||
ConnectorHealth state machine |
open |
||
subscribe_health returns a Channel of HealthEvent |
open |
||
ReconnectPolicy trait |
open |
||
ExponentialBackoff default policy |
open |
||
HealthEvent emitted on every transition |
open |
||
Stack-internal-reconnect connectors emit health uniformly |
open |
||
Same envelope contract for both deployments |
open |
||
In-process gateway is a tokio task |
open |
||
Separate-process gateway is a self-contained binary |
open |
||
Clean exit on SIGINT / SIGTERM on both sides |
open |
||
No app↔gateway control-plane envelopes |
open |
||
MqttConnector implements Connector |
open |
||
MqttRouting carries topic, qos, retained |
open |
||
QoS 0 and 1 supported |
open |
||
Retained-message publish supported |
open |
||
Wildcard subscriptions supported |
open |
||
Username/password authentication |
open |
||
TLS is optional via cargo feature |
open |
||
MQTT 3.1.1 baseline |
open |
||
Tokio sidecar inside the gateway crate |
open |
||
Bridge channels are bounded |
open |
||
Outbound bridge saturation surfaces as BackPressure |
open |
||
Inbound bridge saturation surfaces as DroppedInbound HealthEvent |
open |
||
ConnectorHost builder API |
open |
||
ConnectorGateway builder API |
open |
||
Host registers connector items with the executor |
open |
||
Optional Observer adapter for tracing |
open |
||
NO request/response matching by the framework |
rejected |
||
NO app↔gateway control plane |
rejected |
||
NO persistent outbox or durable buffering |
rejected |
||
NO schema/contract enforcement across the boundary |
rejected |
||
NO protocol-portable Channel<T> |
rejected |
||
NO multi-broker / multi-tenant gateway |
rejected |
||
NO supervision / panic recovery |
rejected |
||
Pre-allocated fixed-block arena |
open |
||
Fail-closed on cap overrun |
open |
||
Lock-after-init panic mode |
open |
||
Allocation accounting API |
open |
||
Thread-safe allocation |
open |
||
EthercatConnector implements Connector |
open |
||
EthercatRouting carries SubDevice and PDO addressing |
open |
||
Single MainDevice per gateway instance |
open |
||
Bus reaches OP before serving traffic |
open |
||
Static PDO mapping per SubDevice |
open |
||
PDO mapping applied during PRE-OP to SAFE-OP transition |
open |
||
Cycle time configurable with millisecond resolution |
open |
||
Missed cycle ticks are skipped not queued |
open |
||
Distributed Clocks bring-up is opt-in |
open |
||
Working-counter-based health policy |
open |
||
Working-counter mismatch degrades health |
open |
||
Tokio sidecar contained inside the connector crate |
open |
||
Bridge channels are bounded |
open |
||
Outbound bridge saturation surfaces as BackPressure |
open |
||
Inbound bridge saturation surfaces as DroppedInbound HealthEvent |
open |
||
Linux raw socket required on gateway host |
open |
||
Outbound payload written to PDI bit slice per routing |
open |
||
Inbound payload read from PDI bit slice per routing |
open |
||
Per-channel routing registry on the gateway |
open |
||
ZenohConnector implements Connector |
open |
||
ZenohRouting carries key_expr and pub/sub QoS fields |
open |
||
JsonCodec is the default codec for Zenoh |
open |
||
Tokio sidecar contained inside the Zenoh connector crate |
implemented |
||
Zenoh bridge channels are bounded |
open |
||
Outbound bridge saturation surfaces as BackPressure |
open |
||
Inbound bridge saturation surfaces as DroppedInbound |
open |
||
Zenoh zero-copy publish via iceoryx2 loan |
open |
||
Zenoh gateway is byte-only on the inbound publish path |
open |
||
ZenohConnector exposes create_querier and create_queryable |
open |
||
ZenohQuerier maps QueryId to envelope correlation_id |
open |
||
ZenohQueryable correlates replies via correlation_id |
open |
||
Multi-reply per query supported |
open |
||
Reply stream end-of-stream framed in payload |
open |
||
Query timeout sourced from options, overridable per-querier |
open |
||
terminate(id) finalizes the upstream zenoh::Query |
open |
||
Codec applied to Q on send and to R on reply |
open |
||
Reply-side inbound saturation emits DroppedInbound |
open |
||
Zenoh session mode is a config knob |
open |
||
NO ReconnectPolicy on Zenoh session loss |
rejected |
||
HealthEvent emitted on every Zenoh session transition |
implemented |
||
Connect and listen locators surfaced to zenoh::Config |
open |
||
zenoh-integration cargo feature gates the real zenoh dep |
implemented |
||
MockZenohSession ships unfeature-gated |
implemented |
||
Linux, macOS, and Windows are supported host operating systems |
implemented |
||
Pure parse function with no I/O |
open |
||
no_std + alloc compatible |
open |
||
quick-xml + serde backend |
open |
||
Parser does not depend on ethercrab or codegen |
open |
||
IR carries identity, PDO maps, mailbox, DC, and OD |
open |
||
Vendor-specific extensions captured as opaque blobs |
open |
||
Parse errors carry line and column |
open |
||
CodegenBackend trait shape |
open |
||
Naming policy is owned by codegen, not the backend |
open |
||
Revision collision handled deterministically |
open |
||
Common PDO entry types deduplicated |
open |
||
Emission target is proc_macro2 TokenStream |
open |
||
Backend crate is the sole ethercrab dependency |
open |
||
One device struct per ESI device entry |
open |
||
SubDeviceIdentity const emitted per device |
open |
||
PDO assignment alternatives emitted as sum type |
open |
||
One PDO struct per assignment alternative |
open |
||
Generated module root exposes a registry |
open |
||
Generated code compiles under no_std + alloc |
open |
||
EsiDevice trait shape |
open |
||
EsiConfigurable trait shape for preop bring-up |
open |
||
Traits live in ethercat-esi-rt, not taktora-connector |
open |
||
Object dictionary emission is a default-off cargo feature |
open |
||
Process image access via bitvec BitSlice |
open |
||
Builder API shape |
open |
||
Output written to OUT_DIR |
open |
||
Cargo rerun-if directives emitted per ESI input |
open |
||
Generated output passes through prettyplease |
open |
||
cargo esi expand emits one device's generated code |
open |
||
cargo esi list enumerates devices in a glob |
open |
||
CLI shares the parser and codegen crates |
open |
||
Verifier ingests ESI XML plus SII binary |
open |
||
Diagnostic output names the differing field |
open |
||
Verifier reuses the parser |
open |
||
Verifier exits non-zero on mismatch |
open |
||
NO CAN / CANopen / EDS support in this round |
rejected |
||
NO proc-macro front-end |
rejected |
||
NO unification of EtherCAT and CANopen runtime traits |
rejected |
||
NO runtime XML parsing |
rejected |
||
NO modification of taktora-connector-ethercat runtime |
rejected |
||
NO automatic vendor library scraping |
rejected |
||
CanConnector implements Connector |
open |
||
CanRouting carries iface, can_id, mask, kind, fd_flags |
open |
||
Linux is the supported host OS for real I/O |
open |
||
socketcan-integration cargo feature gates the real socketcan dep |
open |
||
MockCanInterface ships unfeature-gated |
open |
||
Tokio sidecar contained inside the CAN connector crate |
open |
||
CAN bridge channels are bounded |
open |
||
Outbound bridge saturation surfaces as BackPressure |
open |
||
Inbound bridge saturation surfaces as DroppedInbound |
open |
||
Classical CAN frames supported |
open |
||
CAN-FD frames supported |
open |
||
Channel payload sizing keyed on frame kind |
open |
||
Outbound payload serialised to socketcan frame |
open |
||
Inbound gateway is byte-only on the publish path |
open |
||
CAN ID extended flag preserved end-to-end |
open |
||
Multiple interfaces per gateway |
open |
||
Routing identifies the interface |
open |
||
Per-interface filter is the union of channel masks |
open |
||
Filter recomputed on channel add/remove |
open |
||
Inbound demux to all matching readers |
open |
||
Per-iface routing registry has stable iteration order |
open |
||
ConnectorHealth aggregates per-iface state via worst-of |
open |
||
Error frames consumed internally |
open |
||
error-passive transitions to Degraded |
open |
||
bus-off transitions to Down and triggers reconnect |
open |
||
ReconnectPolicy reused; ExponentialBackoff default |
open |
||
HealthEvent emitted on every transition |
open |
||
Error frames not exposed to plugin |
open |
||
NO DBC parsing or typed signal extraction in taktora-connector-can |
rejected |
||
NO ISO-TP or J1939 support in taktora-connector-can |
rejected |
||
NO CAN-XL support |
rejected |
||
NO plugin-visible error-frame channel |
rejected |
||
NO can-restart-ms management from the gateway |
rejected |
||
No transport-specific types in fieldbus-od-core |
open |
||
no_std + alloc, no mandatory serde |
open |
||
OD type surface |
open |
||
ethercat-esi re-exports lifted types |
open |
||
canopen-eds uses fieldbus-od-core types |
open |
||
Pure parse function with no I/O |
open |
||
no_std + alloc, no upstream coupling |
open |
||
serde-derive INI backend |
open |
||
Parse errors carry line and column |
open |
||
Unknown sections captured as RawSection |
open |
||
Liberal parsing — warn and continue on quirks |
open |
||
IR carries identity, OD, PDO comm + maps |
open |
||
CodegenBackend trait shape |
open |
||
Naming policy is owned by codegen, not the backend |
open |
||
Revision collision handled deterministically |
open |
||
Common PDO entry types deduplicated |
open |
||
Emission target is proc_macro2 TokenStream |
open |
||
One EDS file equals one device |
open |
||
Backend crate is the sole canopen-eds-rt dependency |
open |
||
One device struct per EDS file |
open |
||
Identity const emitted per device |
open |
||
PDO declarations emitted as sum types |
open |
||
Dummy entries skipped in PDO payload structs |
open |
||
Generated module root exposes a registry |
open |
||
Bring-up SDO writes emitted from EDS |
open |
||
Object dictionary emission is a default-off cargo feature |
open |
||
Generated code compiles under no_std + alloc |
open |
||
CanOpenDevice trait shape |
open |
||
CanOpenConfigurable trait shape for bring-up |
open |
||
Traits live in canopen-eds-rt, not taktora-connector-can |
open |
||
Frame payloads use heapless::Vec<u8, 8> |
open |
||
Frame-per-PDO dispatch shape |
open |
||
CanOpenError variant surface |
open |
||
RPDO rejected outside Operational state |
open |
||
Builder API shape |
open |
||
Output written to OUT_DIR |
open |
||
Cargo rerun-if directives emitted per EDS input |
open |
||
Generated output passes through prettyplease |
open |
||
Parser warnings surface as cargo warnings |
open |
||
cargo eds expand emits one device's generated code |
open |
||
cargo eds list enumerates devices in a glob |
open |
||
CLI shares the parser and codegen crates |
open |
||
Verifier ingests EDS plus JSON SDO-dump |
open |
||
Diagnostic output names the differing field |
open |
||
Verifier reuses the parser |
open |
||
Verifier exits non-zero on mismatch |
open |
||
SDO-dump JSON schema versioned |
open |
||
NO DCF support this round |
rejected |
||
NO CAN-FD payload support in PdoOut |
rejected |
||
NO proc-macro front-end |
rejected |
||
NO unification of EtherCAT and CANopen runtime traits |
rejected |
||
NO runtime EDS parsing |
rejected |
||
NO modification of taktora-connector-can runtime |
rejected |
||
NO automatic vendor library scraping |
rejected |
||
NO live-bus verifier this round |
rejected |