Skip to content

CanOpenNodeOptions Class

Runtime configuration for a CanOpenNode. All values are captured at construction time and treated as immutable for the node's lifetime; use With(...) to derive a modified template for tests.

public sealed class CanOpenNodeOptions

Inheritance Object → CanOpenNodeOptions

Remarks

The SDO client timeout defaults to one second, which matches the widely-used CANopen master libraries (canopen.py, CANopenNode host tools). The heartbeat and SYNC producers are off by default — enable them explicitly through the node's public API when needed.

Properties

CanOpenNodeOptions.DefaultTpdoEventTimerInterval Property

Interval used by the built-in TPDO event-timer scheduler for TPDOs configured with TpdoTransmission.EventTimer. May be overridden per-PDO at configuration time.

public System.TimeSpan DefaultTpdoEventTimerInterval { get; init; }

Property Value

TimeSpan

CanOpenNodeOptions.EmitControllerErrorEmcy Property

Emit optional 8120h EMCYs when the CAN controller is observed error passive. Defaults to false. Uses the shared bus-state monitor (50 ms polling plus error/fault hints). Once observed, the cause remains active through bus-off or an unknown reading until error-active, error-warning or no-error state is observed. It contributes bits 4 and 0 to 1001h; the last repaired cause emits 0000h.

public bool EmitControllerErrorEmcy { get; init; }

Property Value

Boolean

Remarks

Does not enable overrun or recovered-from-bus-off EMCYs. An initially passive controller is reported when the node enters Pre-Operational. Existing With methods preserve this setting.

CanOpenNodeOptions.EmitGuardingErrorEmcy Property

Emit optional 8130h EMCYs for heartbeat-consumer timeouts and this node's life- guarding timeout. Defaults to false; timeout events remain available regardless. Enabled errors contribute bits 4 and 0 to 1001h until reception, removal/reconfiguration of the watch, a guarding poll or disabling life guarding ends their cause. The last repaired communication error emits 0000h.

public bool EmitGuardingErrorEmcy { get; init; }

Property Value

Boolean

Remarks

Does not enable controller-state or node-guarding-consumer EMCYs. Existing With copy methods preserve this setting.

CanOpenNodeOptions.EnableChangeOfStateSrdo Property

A write by the application to an object mapped in a transmit SRDO transmits the SRDO at once (CiA DSP 304 V1.0 §8.1, "event-driven … to ensure fast reaction"), like EnableChangeOfStateTpdo. The refresh cycle restarts from that transmission.

public bool EnableChangeOfStateSrdo { get; init; }

Property Value

Boolean

CanOpenNodeOptions.EnableChangeOfStateTpdo Property

When true (default), a local application write to an OD entry that is mapped in an event-driven TPDO (EventDriven) automatically emits that TPDO — change-of-state triggering per FR-CO-006 / CiA 301 §7.3.6, without the application having to call TriggerTpdoAsync manually. Only application-originated writes count: bus-originated writes (SDO server download commit, RPDO unpack) run on the node's actor thread and never re-trigger TPDOs, so no bus echo loops can form. Set to false to restore the pure manual-trigger behavior.

public bool EnableChangeOfStateTpdo { get; init; }

Property Value

Boolean

CanOpenNodeOptions.ErrorHistoryCapacity Property

The entries of the pre-defined error field 1003h (CiA 301 §7.5.2.4), 0..254. 0, the default, leaves the optional object out, and an application may declare it itself. A device description that declares the object raises this to its highest entry. The node enters every EMCY it transmits except 0000h, the newest at sub-index 01h, the first two manufacturer-specific bytes as the additional information; a full history drops the oldest. Writing 0 to sub-index 00h empties it. An NMT reset leaves it, 1010h does not store it, so power-off ends it. Kept by With(...); WithErrorHistoryCapacity(int) replaces it.

public int ErrorHistoryCapacity { get; init; }

Property Value

Int32

CanOpenNodeOptions.EventQueueCapacity Property

How many ordinary events may wait in the dispatch queue that feeds CanOpenNode.HeartbeatReceived, CanOpenNode.SyncReceived, CanOpenNode.RpdoReceived, CanOpenNode.NmtCommandReceived, CanOpenNode.NodeGuardingReceived and CanOpenNode.LifeGuardingEvent. When a subscriber falls behind, the oldest of those events is discarded so the queue never holds more than this many of them and the actor loop is never blocked by a slow handler. Defaults to 64. CanOpenNode.HeartbeatTimeout, CanOpenNode.NodeGuardingTimeout and CanOpenNode.EmcyReceived travel on the same queue, in the order they were raised, but are never discarded to make room: a guarding consumer that misses one treats a silent peer as alive. They can make the queue longer than this capacity while a handler is stuck, but not without bound. A timeout for a producer whose timeout is already waiting is folded into it, and so is an EMCY identical to one already waiting, provided nothing else about that producer was queued in between. Each EMCY producer may have at most this many distinct emergencies waiting; the surplus from it is discarded until its backlog drains, and one CanOpenNode.BackgroundExceptionOccurred report is raised per such burst. CanOpenNode.BackgroundExceptionOccurred is not part of this queue and not bounded by it: it is delivered on the thread pool, one report at a time.

public int EventQueueCapacity { get; init; }

Property Value

Int32

CanOpenNodeOptions.Lss Property

Layer setting services (CiA 305). null (the default) leaves them off, unless the device description the node is opened with sets LSS_Supported. An instance turns them on, and Enabledfalse turns them off even when the file says they are supported. A node-id of 0xFF is legal only while they are on.

public CanKit.Pro.CANopen.Lss.LssSlaveOptions? Lss { get; init; }

Property Value

LssSlaveOptions

CanOpenNodeOptions.MaxSdoTransferBytes Property

Upper bound (in bytes) on the total payload of a single segmented SDO transfer, applied both to server-side segmented downloads (initiator's declared 32-bit length) and to client-side segmented upload responses (server's declared 32-bit length). Bounds a hostile / buggy peer's ability to drive us into an unbounded new byte[declaredLen] allocation: any initiate declaring more than this many bytes is aborted with the CiA 301 "out of memory" SDO abort code (0x05040005) rather than being honored. Fixed-width OD entries are additionally capped to their declared size at the type-check layer above; this limit only matters for Domain payloads (and for the client's upload path where the OD type is not yet known). Defaults to 1 MiB, which is well above any realistic CiA-301 profile payload but small enough to reject an accidental or malicious 4 GiB initiate outright.

public int MaxSdoTransferBytes { get; init; }

Property Value

Int32

CanOpenNodeOptions.PdoCount Property

Number of PDO records per direction (1..512), default 4. An EDS/DCF raises this to its highest declared PDO. PDOs above 4 require an explicit COB-ID.

public int PdoCount { get; init; }

Property Value

Int32

CanOpenNodeOptions.Profile Property

Device or tool. Read when 1F80h is created: Device leaves the self-start and slave-start suppress bits clear, Tool sets both. The profile does not change for the life of the node. Defaults to device.

public CanKit.Pro.CANopen.CanOpenNodeProfile Profile { get; init; }

Property Value

CanOpenNodeProfile

CanOpenNodeOptions.RespondToNodeGuardingRtr Property

When true this node answers a Node-Guarding RTR (COB-ID 0x700 + own node-id) with a one-byte data frame carrying the current NMT state (bits 0..6) and an alternating toggle bit (bit 7), per CiA 301 §7.2.8.3.2.1. Ignored when the heartbeat producer is active (CiA 301 §7.2.8.3.2.2 makes heartbeat and node-guarding mutually exclusive on the same node). Defaults to true so slaves are answered out of the box.

false also keeps producer-side life guarding off: guarding starts with the first RTR the node answers, so with no RTR answered LifeGuardingEvent is never raised, whatever 100Ch and 100Dh hold.

public bool RespondToNodeGuardingRtr { get; init; }

Property Value

Boolean

CanOpenNodeOptions.SdoBlockCrcSupported Property

When true this node advertises CRC-16/XMODEM support on block-transfer initiates (cc / sc bit) and both computes and validates the CRC on the end-of-block frame. The peer must also set its CRC bit for the CRC to be exchanged (per CiA 301 §7.2.4.3.11 and §7.2.4.3.15 the CRC is only valid when both endpoints set cc and sc in the initiate, and is 0 otherwise). Defaults to true.

public bool SdoBlockCrcSupported { get; init; }

Property Value

Boolean

CanOpenNodeOptions.SdoBlockMaxRetransmissions Property

Maximum number of sub-block retransmissions per block transfer before the node aborts (CiA 301 §7.2.4.3.10 for download, §7.2.4.3.14 for upload): on a partial sub-block ACK (ackseq < segments sent) the sender rewinds to the first unconfirmed segment and resends, up to this many times per transfer — a bound against peers that never confirm progress. Applies to the download client and the upload server alike. 0 restores the previous MVP behavior (abort on the first partial ACK). Defaults to 3.

public int SdoBlockMaxRetransmissions { get; init; }

Property Value

Int32

CanOpenNodeOptions.SdoBlockSize Property

Preferred block size (segments per sub-block, 1..127) that this node advertises when it acts as a block-transfer receiver (server for download, client for upload). CiA 301 §7.2.4.3.9 (download) and §7.2.4.3.13 (upload) bound blksize to 0 < blksize < 128, so the receiver may choose any value in [1,127]; peers with a smaller window will re-negotiate downward via their own initiate. Defaults to 127.

public byte SdoBlockSize { get; init; }

Property Value

Byte

CanOpenNodeOptions.SdoBlockThresholdBytes Property

Auto-select threshold (bytes) at or above which the SDO client uses block transfer (FR-CO-004 / CiA 301 §7.2.4.3.8–7.2.4.3.11, block download) for an Auto download instead of the segmented protocol. Below the threshold the payload length picks the codec: expedited for 1..4 bytes, segmented above that. Uploads never auto-switch to block because the length is unknown until the server replies; callers can bypass the threshold in either direction by explicitly passing Block. Defaults to 128 bytes.

public int SdoBlockThresholdBytes { get; init; }

Property Value

Int32

CanOpenNodeOptions.SdoServerTimeout Property

Server-side SDO session timeout: how long an open segmented server transfer (download or upload) may idle without the peer sending the next segment / segment-ack before the session is torn down and an SDO abort (SdoProtocolTimedOut) is emitted. Prevents a client that starts a segmented transfer and then goes silent from pinning the server's single session slot forever (the block-transfer server side already had this guard; CiA 301 leaves the concrete value to the implementation). Deliberately longer than SdoTimeout so a well-behaved client always times out first. Defaults to 5 s.

public System.TimeSpan SdoServerTimeout { get; init; }

Property Value

TimeSpan

CanOpenNodeOptions.SdoTimeout Property

Client-side SDO transfer timeout, applied to every request (initiate as well as each segment ack). In a block download it also restarts at every confirmed segment of a sub-block, so it measures the server's silence and not the time a sub-block takes to send. On a bus without echo that confirmation is the driver accepting the frame, not the frame reaching the wire: a driver queue holding more than this much bus time still outlasts the timer, and raising it is the remedy. CiA 301 does not specify a fixed value; one second matches common production tooling and is aggressive enough for tests on a virtual bus.

public System.TimeSpan SdoTimeout { get; init; }

Property Value

TimeSpan

CanOpenNodeOptions.SrdoConfigurationCheckInterval Property

How often a node with SRDOs recalculates the checksums of its existing SRDOs and compares them with 13FFh while 13FEh says A5h — CiA 319 v2.0.0 §5.3: the SRD "should validate the consistency of its safety-related configuration by periodically recalculating the CRC". A mismatch sets 13FEh to 00h; in Operational every SRDO is then ConfigurationInvalid, as it would be at the transition. null, the default, runs no periodic check: CiA 319 names no interval, and the checks at the write of A5h, after a reset and at the transition to Operational run regardless. Kept by With(Nullable<TimeSpan>, Nullable<TimeSpan>, Nullable<TimeSpan>, Nullable<int>, Nullable<int>, Nullable<int>, Nullable<byte>, Nullable<bool>, Nullable<int>, Nullable<bool>, Nullable<bool>, Nullable<bool>, Nullable<CanOpenNodeProfile>, Nullable<int>, Nullable<bool>, Nullable<int>); WithSrdoConfigurationCheckInterval(Nullable<TimeSpan>) replaces it.

public System.Nullable<System.TimeSpan> SrdoConfigurationCheckInterval { get; init; }

Property Value

Nullable<TimeSpan>

CanOpenNodeOptions.SrdoCount Property

How many SRDOs (CiA DSP 304 V1.0) this node implements, 0..64. With 0 — the default — the node creates none of the safety objects 1300h–13FFh and is a plain CiA 301 node (§9.4: "The implementation of CANopen Safety shall be allowed only in safety devices"). A device description that declares SRDO records raises the count to the highest record it declares. The safety API is reached through node.Safety().

public int SrdoCount { get; init; }

Property Value

Int32

CanOpenNodeOptions.WritableCommunicationParameters Property

When true, the PDO communication and mapping records of the node's built-in object dictionary (1400h/1600h/1800h/1A00h + n − 1 for every PDO up to PdoCount; 1400h–1403h … 1A00h–1A03h for the default four) are writable over SDO, so a master or configuration tool can configure this node's PDOs over the bus; every accepted write takes effect in the PDO engine. When false (default) those records are read-only on the bus: the application configures its PDOs through ConfigureTpdo / ConfigureRpdo, and the records describe that configuration truthfully to a master without offering to change it (CiA 301 permits ro PDO parameter records, objects overview footnote). The SYNC, EMCY, heartbeat and guarding objects are writable in either case, as CiA 301 prescribes for them, and so are the safety objects, as EN 50325-5:2010 does.

public bool WritableCommunicationParameters { get; init; }

Property Value

Boolean

Methods

CanOpenNodeOptions.With(Nullable<TimeSpan>, Nullable<TimeSpan>, Nullable<TimeSpan>, Nullable<int>, Nullable<int>, Nullable<int>, Nullable<byte>, Nullable<bool>, Nullable<int>, Nullable<bool>, Nullable<bool>, Nullable<bool>, Nullable<CanOpenNodeProfile>) Method

Returns a copy of this options record with the provided overrides. The 1.3.0 signature, kept so that callers compiled against it still bind; source callers resolve to the overload with every parameter optional.

public CanKit.Pro.CANopen.CanOpenNodeOptions With(System.Nullable<System.TimeSpan> sdoTimeout, System.Nullable<System.TimeSpan> sdoServerTimeout, System.Nullable<System.TimeSpan> defaultTpdoEventTimerInterval, System.Nullable<int> eventQueueCapacity, System.Nullable<int> maxSdoTransferBytes, System.Nullable<int> sdoBlockThresholdBytes, System.Nullable<byte> sdoBlockSize, System.Nullable<bool> sdoBlockCrcSupported, System.Nullable<int> sdoBlockMaxRetransmissions, System.Nullable<bool> respondToNodeGuardingRtr, System.Nullable<bool> enableChangeOfStateTpdo, System.Nullable<bool> writableCommunicationParameters, System.Nullable<CanKit.Pro.CANopen.CanOpenNodeProfile> profile);

Parameters

sdoTimeout Nullable<TimeSpan>

sdoServerTimeout Nullable<TimeSpan>

defaultTpdoEventTimerInterval Nullable<TimeSpan>

eventQueueCapacity Nullable<Int32>

maxSdoTransferBytes Nullable<Int32>

sdoBlockThresholdBytes Nullable<Int32>

sdoBlockSize Nullable<Byte>

sdoBlockCrcSupported Nullable<Boolean>

sdoBlockMaxRetransmissions Nullable<Int32>

respondToNodeGuardingRtr Nullable<Boolean>

enableChangeOfStateTpdo Nullable<Boolean>

writableCommunicationParameters Nullable<Boolean>

profile Nullable<CanOpenNodeProfile>

Returns

CanOpenNodeOptions

CanOpenNodeOptions.With(Nullable<TimeSpan>, Nullable<TimeSpan>, Nullable<TimeSpan>, Nullable<int>, Nullable<int>, Nullable<int>, Nullable<byte>, Nullable<bool>, Nullable<int>, Nullable<bool>, Nullable<bool>, Nullable<bool>, Nullable<CanOpenNodeProfile>, Nullable<int>, Nullable<bool>) Method

The previous full signature, retained for callers compiled against it.

public CanKit.Pro.CANopen.CanOpenNodeOptions With(System.Nullable<System.TimeSpan> sdoTimeout, System.Nullable<System.TimeSpan> sdoServerTimeout, System.Nullable<System.TimeSpan> defaultTpdoEventTimerInterval, System.Nullable<int> eventQueueCapacity, System.Nullable<int> maxSdoTransferBytes, System.Nullable<int> sdoBlockThresholdBytes, System.Nullable<byte> sdoBlockSize, System.Nullable<bool> sdoBlockCrcSupported, System.Nullable<int> sdoBlockMaxRetransmissions, System.Nullable<bool> respondToNodeGuardingRtr, System.Nullable<bool> enableChangeOfStateTpdo, System.Nullable<bool> writableCommunicationParameters, System.Nullable<CanKit.Pro.CANopen.CanOpenNodeProfile> profile, System.Nullable<int> srdoCount, System.Nullable<bool> enableChangeOfStateSrdo);

Parameters

sdoTimeout Nullable<TimeSpan>

sdoServerTimeout Nullable<TimeSpan>

defaultTpdoEventTimerInterval Nullable<TimeSpan>

eventQueueCapacity Nullable<Int32>

maxSdoTransferBytes Nullable<Int32>

sdoBlockThresholdBytes Nullable<Int32>

sdoBlockSize Nullable<Byte>

sdoBlockCrcSupported Nullable<Boolean>

sdoBlockMaxRetransmissions Nullable<Int32>

respondToNodeGuardingRtr Nullable<Boolean>

enableChangeOfStateTpdo Nullable<Boolean>

writableCommunicationParameters Nullable<Boolean>

profile Nullable<CanOpenNodeProfile>

srdoCount Nullable<Int32>

enableChangeOfStateSrdo Nullable<Boolean>

Returns

CanOpenNodeOptions

CanOpenNodeOptions.With(Nullable<TimeSpan>, Nullable<TimeSpan>, Nullable<TimeSpan>, Nullable<int>, Nullable<int>, Nullable<int>, Nullable<byte>, Nullable<bool>, Nullable<int>, Nullable<bool>, Nullable<bool>, Nullable<bool>, Nullable<CanOpenNodeProfile>, Nullable<int>, Nullable<bool>, Nullable<int>) Method

Returns a copy of this options record with the provided overrides, validated like the options a node is opened with. The optional PDO count override is 1..512. Lss is kept; WithLss(LssSlaveOptions) replaces it. SrdoConfigurationCheckInterval is kept likewise; WithSrdoConfigurationCheckInterval(Nullable<TimeSpan>) replaces it.

public CanKit.Pro.CANopen.CanOpenNodeOptions With(System.Nullable<System.TimeSpan> sdoTimeout=null, System.Nullable<System.TimeSpan> sdoServerTimeout=null, System.Nullable<System.TimeSpan> defaultTpdoEventTimerInterval=null, System.Nullable<int> eventQueueCapacity=null, System.Nullable<int> maxSdoTransferBytes=null, System.Nullable<int> sdoBlockThresholdBytes=null, System.Nullable<byte> sdoBlockSize=null, System.Nullable<bool> sdoBlockCrcSupported=null, System.Nullable<int> sdoBlockMaxRetransmissions=null, System.Nullable<bool> respondToNodeGuardingRtr=null, System.Nullable<bool> enableChangeOfStateTpdo=null, System.Nullable<bool> writableCommunicationParameters=null, System.Nullable<CanKit.Pro.CANopen.CanOpenNodeProfile> profile=null, System.Nullable<int> srdoCount=null, System.Nullable<bool> enableChangeOfStateSrdo=null, System.Nullable<int> pdoCount=null);

Parameters

sdoTimeout Nullable<TimeSpan>

sdoServerTimeout Nullable<TimeSpan>

defaultTpdoEventTimerInterval Nullable<TimeSpan>

eventQueueCapacity Nullable<Int32>

maxSdoTransferBytes Nullable<Int32>

sdoBlockThresholdBytes Nullable<Int32>

sdoBlockSize Nullable<Byte>

sdoBlockCrcSupported Nullable<Boolean>

sdoBlockMaxRetransmissions Nullable<Int32>

respondToNodeGuardingRtr Nullable<Boolean>

enableChangeOfStateTpdo Nullable<Boolean>

writableCommunicationParameters Nullable<Boolean>

profile Nullable<CanOpenNodeProfile>

srdoCount Nullable<Int32>

enableChangeOfStateSrdo Nullable<Boolean>

pdoCount Nullable<Int32>

Returns

CanOpenNodeOptions

Exceptions

ArgumentOutOfRangeException
A resulting value is out of its range.

CanOpenNodeOptions.WithErrorHistoryCapacity(int) Method

Returns a copy of this options record with ErrorHistoryCapacity replaced.

public CanKit.Pro.CANopen.CanOpenNodeOptions WithErrorHistoryCapacity(int capacity);

Parameters

capacity Int32

Returns

CanOpenNodeOptions

Exceptions

ArgumentOutOfRangeException
capacity is outside 0..254.

CanOpenNodeOptions.WithLss(LssSlaveOptions) Method

Returns a copy with Lss replaced. Pass null to turn layer setting services back off unless a device description enables them.

public CanKit.Pro.CANopen.CanOpenNodeOptions WithLss(CanKit.Pro.CANopen.Lss.LssSlaveOptions? lss);

Parameters

lss LssSlaveOptions

Returns

CanOpenNodeOptions

CanOpenNodeOptions.WithSrdoConfigurationCheckInterval(Nullable<TimeSpan>) Method

Returns a copy with SrdoConfigurationCheckInterval replaced — a template's way to turn the periodic check on, off (null) or to another interval, validated like the options a node is opened with (Codex on #329).

public CanKit.Pro.CANopen.CanOpenNodeOptions WithSrdoConfigurationCheckInterval(System.Nullable<System.TimeSpan> interval);

Parameters

interval Nullable<TimeSpan>

Returns

CanOpenNodeOptions

Exceptions

ArgumentOutOfRangeException
interval is not positive.