ICanOpenSafety Interface¶
CANopen Safety (CiA DSP 304 V1.0) on a node: the SRDOs it produces and consumes, the global failsafe command, and — for a master or tool — the configuration and verification of a peer's safety parameters, run as the configuration entity of CiA 319 v2.0.0 (identity verification, the configuration steps, the storage, the checksum of an SRVT the peer does not implement). Reached through Safety(this ICanOpenNode). A node has SRDOs only when opened with SrdoCount > 0 or a device description that declares them.
Remarks¶
This library is not developed to IEC 61508 / DIN V VDE 0801 and claims no safety integrity level. It implements the data transport of DSP 304 V1.0 — the frame pair, the timing checks, the objects, the checksum — and leaves the diverse redundancy of §9.5 ("built by two different ways", "compared … in the application") and the safe state to the device.
Properties¶
ICanOpenSafety.SrdoCount Property¶
The number of SRDO records this node holds (0..64).
Property Value¶
Methods¶
ICanOpenSafety.CommitSafetyConfiguration() Method¶
§9.2 for a locally configured node: writes 13FFh:n for every record and
then 13FEh = A5h. Until this is called the configuration is not valid and no SRDO
runs in Operational.
ICanOpenSafety.ConfigurePeerSafetyAsync(byte, PeerSafetyConfiguration, CancellationToken) Method¶
The configuration entity of CiA 319 v2.0.0 clause 5 on the §9.2 Figure 9
transaction. First the peer's identity (CiA 319 §5.2): 1018h:01, :02 and :03 are uploaded
and compared with the bound description's own 1018h:01–03 — "the entries in the EDS" —
as declared (ParameterValue, DefaultValue where none); a difference ends the call with those
entries as the mismatches, and nothing is written. §5.2 requires all three of an SRD, where
CiA 301 makes :02 and :03 optional: the file must declare them with a value, and the peer
must implement them — one that aborts an upload of them is not an SRD this procedure can
configure, and the abort propagates, unless an earlier entry already differed, when it is
reported as a mismatch with no bytes read. The file's [DeviceInfo] numbers, where
set, must agree with its 1018h entries; a file that contradicts itself, or whose three
entries are all 0, describes no device and is refused before the first frame. Every transfer
the call makes whatever the peer answers — the identity, 13FFh:00, 1300h, the checksums of
the SRDOs named, 13FEh, the 1010h sub-index asked for — passes the peer-SDO gate before the
first frame; the transfers that depend on the peer's count — sub-index 01h of every record
up to it and every 13FFh:n, for the SRDOs the configuration does not name too — pass it
once 13FFh:00 is read, before the first write, and a count above the bound description's
highest SRDO record is refused there, since the gate could let no record above it through.
Then (§5.3 step 1) it downloads 1300h, every record (deleted first,
created last) and the checksums 13FFh:n, (step 2) reads everything back and compares byte for
byte, and only then (step 3) writes 13FEh = A5h and reads it back — step 4 is the peer's own
check of the checksums, and a peer that found one wrong answers that readback with 0. When
Storage asks for it (step 5), the "save" signature
is then downloaded to 1010h at that sub-index, so the acknowledged configuration outlasts
the peer's reset; a store the peer aborts is reported in the result
(StorageAbort), the acknowledgement standing. A tx SRDO whose
communication record the bound description declares without sub-index 3 is one the peer is
taken not to hold an SRVT for (CiA 319 §6.2): the configuration must say 20 ms there — the
value such a peer checksums — and the sub-index is written and read back all the same, so
that a peer which does hold it ends with 20 ms rather than a value from an earlier
configuration (a delete writes sub-index 1 only); a peer that aborts the write with
0609 0011h (sub-index does not exist) does not implement it and is not asked to read it
back, one that aborts it with 0601 0002h (read-only) holds it and is. A sub-index 3 the
description declares read-only is not written, only read back; the configuration must say
20 ms there too. Before the first frame, every mapping entry is checked against
the peer's bound EDS/DCF (declared, mappable, of a fixed width equal to the entry's, access
in the SRDO's direction), since
the deletion comes first. Every transfer passes the peer-SDO gate. The peer's SDO
channel is reserved for the whole transaction: it waits for a call to that peer already in
flight, and a concurrent SDO call of this node to that peer is refused as already in flight.
The transaction works from the description and the configuration as they were when it
started — when it owns the peer's channel, after any call it waited for: its pre-check, the
gate of every transfer, the identity, the writes and the readback use copies taken then, not
the bound description or the caller's configuration. A rebind, an unbind
or an edit in place of either before that moment is seen; one after it takes effect for the
next call, not half-way through this one.
An SDO abort, a timeout or a gate refusal propagates as from SdoDownloadAsync; one from the
step-5 store comes after the acknowledgement, which the peer then holds unstored.
The peer's 13FEh is 0 once at least one parameter write has been
accepted, because every such write clears it; an abort before that — for example
0800 0022h from an Operational peer, which refuses the first write — leaves it unchanged.
System.Threading.Tasks.Task<CanKit.Pro.CANopen.Safety.PeerSafetyResult> ConfigurePeerSafetyAsync(byte peerNodeId, CanKit.Pro.CANopen.Safety.PeerSafetyConfiguration configuration, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
Parameters¶
peerNodeId Byte
configuration PeerSafetyConfiguration
cancellationToken CancellationToken
Returns¶
Exceptions¶
PeerSdoAccessException
No description is bound for the peer (the
exception names 1018h:01, the first transfer, which has nothing to be compared with), or
the bound description does not declare one of the transfers the call makes whatever the
peer answers — 1018h:01–03, 13FFh:00, 1300h, 13FFh:n of an SRDO named, 13FEh, the 1010h
sub-index Storage names — refused before the first
frame by the gate that would refuse the transfer; or, once the count is read, sub-index 01h
of a record up to it or 13FFh:n of an SRDO the configuration does not name — refused
before the first write, likewise.
InvalidOperationException
The bound description declares a 1018h entry
without a value this implementation reads (a plain number; a $NODEID formula is no
identity), contradicts itself (a [DeviceInfo] number
set and unlike its 1018h entry) or has 1018h:01–03 all 0, so it carries no identity to
verify the peer against (CiA 319 §5.2) — refused before the first frame; or the peer's
13FFh:00 is not exactly one byte (it is UNSIGNED8; none, two or four bytes are refused, a
longer one is not cut to its low byte), or the count is above 64 (§8.4.2.2) or above the
bound description's highest SRDO record (the gate implies no record above it, so the
SRDOs the peer has beyond the file could not be deleted) — refused before any further
frame, nothing written; or the bound description declares ro or const a pair
the configuration downloads — 13FFh:n, 13FEh, 1300h, a record entry, the 1010h sub-index
asked for — which a peer honouring its file refuses with 0601 0002h: refused before the
first frame, or for an SRDO the configuration does not name once the count is read, before
the first write. A sub-index 3 declared read-only is no download (above).
ArgumentException
The configuration names an SRDO above the peer's count,
or maps an object the peer's bound EDS/DCF does not declare, does not flag mappable, declares
with another width or with a type without a fixed width (a string, a domain: an SRDO maps
fixed-width objects only, this implementation's rule) or without a type this implementation
knows (no DataType, or an unknown code: its width cannot be known), or does not make
accessible in the
SRDO's direction — checked before
the first frame, because §9.2 deletes every SRDO of the peer first; or gives a tx SRDO whose
record the description declares without a writable sub-index 3 an SRVT other than 20 ms
(CiA 319 §6.2). What only the peer can judge stays the peer's.
ICanOpenSafety.ConfigureSrdoConsumer(int, SrdoMapping, TimeSpan, TimeSpan, Nullable<uint>, Nullable<uint>) Method¶
Writes record srdoNumber as a consumer: direction rx, SCT, SRVT, mapping and COB-IDs. See ConfigureSrdoProducer(int, SrdoMapping, TimeSpan, Nullable<uint>, Nullable<uint>) for the rest.
void ConfigureSrdoConsumer(int srdoNumber, CanKit.Pro.CANopen.Safety.SrdoMapping mapping, System.TimeSpan safeguardCycleTime, System.TimeSpan validationTime, System.Nullable<uint> cobId1=null, System.Nullable<uint> cobId2=null);
Parameters¶
srdoNumber Int32
mapping SrdoMapping
safeguardCycleTime TimeSpan
validationTime TimeSpan
ICanOpenSafety.ConfigureSrdoProducer(int, SrdoMapping, TimeSpan, Nullable<uint>, Nullable<uint>) Method¶
Writes record srdoNumber as a producer: direction tx,
refresh time, the mapping (plain and inverted sub-indices), the COB-IDs — the
pre-defined pair of Table 4 for SRDO 1 of a node-id ≤ 64 when none is given. The SRDO
is deleted first and created last, as §8.4.2.2 requires for a mapping change. Writes
13FEh to 0; call CommitSafetyConfiguration() afterwards. The writes are
checked whole before the first one: a configuration the dictionary would refuse part-way
changes nothing.
void ConfigureSrdoProducer(int srdoNumber, CanKit.Pro.CANopen.Safety.SrdoMapping mapping, System.TimeSpan refreshTime, System.Nullable<uint> cobId1=null, System.Nullable<uint> cobId2=null);
Parameters¶
srdoNumber Int32
mapping SrdoMapping
refreshTime TimeSpan
Exceptions¶
InvalidOperationException
The node has no SRDOs, or is Operational (0800 0022h).
ArgumentOutOfRangeException
The number is not 1..SrdoCount, or a time is out of range.
ArgumentException
A value the dictionary refuses (the abort code is in the message; nothing is written) — among them a mapped object without a fixed width (a string or a domain, 0604 0041h: an SRDO maps fixed-width objects only, this implementation's rule) — or no COB-ID for a node-id above 64.
ICanOpenSafety.DeleteSrdo(int) Method¶
Sets the direction of the record to 0: the SRDO does not exist.
Parameters¶
srdoNumber Int32
ICanOpenSafety.GetSrdoState(int) Method¶
The current validity of an SRDO: a snapshot of the actor's view. Right after the node is opened its records are taken on the actor's first turn, so a read before any call that round-trips the actor (State, say) has returned may still show None.
Parameters¶
srdoNumber Int32
Returns¶
Exceptions¶
ArgumentOutOfRangeException
The number is not 1..SrdoCount — on a node without SRDOs, every number.
ObjectDisposedException
The node has been disposed.
ICanOpenSafety.ObserveForeignSrdoAsync(byte, uint, ReadOnlyMemory<byte>, ReadOnlyMemory<byte>, CanOpenDeviceDescription, IForeignPdoSink, CancellationToken) Method¶
Splits an SRDO pair of another node into sink, like ObserveForeignPdoAsync(byte, uint, ReadOnlyMemory<byte>, CanOpenDeviceDescription, IForeignPdoSink, CancellationToken): the existing record whose live 1301h–1340h:05 equals cobId1 (the file is the fallback when the upload fails; a record whose direction is not 1 or 2, live or in the file, does not match: a deleted one may have kept the ids another SRDO now uses), the pair checked for equal length and bitwise inversion, the mapping read live from 1381h–13C0h or from the file — either only when each even sub-index up to the count repeats the odd one before it, the rule the device's own validator and loader apply (CiA DSP 304 §8.4.2.2, 1381h–13C0h); otherwise the pair is not decoded and the reason names the slot. A live even slot that was read and differs from its odd slot makes the pair not decoded, with no fallback to the file: live wins. A live slot that cannot be read, even or odd, means the live mapping is not read, and the file decides. Signals carry Srdo and the SRDO number. SRVT and SCT are the caller's to judge: it holds the timestamps. Nothing is written to this node's dictionary. The live mapping is read in full whenever its count is: the peer-SDO gate lets through every slot of an SRDO record the bound file implies, declared or not. A record whose COB-ID 1 word has a bit above bit 10 set, or a mapping with a dummy entry, is not decoded. The records searched are those peerDescription implies: up to its highest declared communication or mapping record, as the loader and the gate read it. The live reads of one observation are one snapshot of the peer: the peer's SDO channel is taken without waiting and held to the end, so a safety transaction that starts meanwhile waits for it and another SDO call of this node to that peer is refused as in flight; a channel busy at the start makes every live read of that observation "already in flight", and the whole snapshot is the file's.
System.Threading.Tasks.Task<CanKit.Pro.CANopen.Safety.ForeignSrdoObserveResult> ObserveForeignSrdoAsync(byte peerNodeId, uint cobId1, System.ReadOnlyMemory<byte> frame1, System.ReadOnlyMemory<byte> frame2, CanKit.Pro.CANopen.CanOpenDeviceDescription peerDescription, CanKit.Pro.CANopen.IForeignPdoSink sink, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
Parameters¶
peerNodeId Byte
cobId1 UInt32
frame1 ReadOnlyMemory<Byte>
frame2 ReadOnlyMemory<Byte>
peerDescription CanOpenDeviceDescription
sink IForeignPdoSink
cancellationToken CancellationToken
Returns¶
Task<ForeignSrdoObserveResult>
ICanOpenSafety.SendGlobalFailsafeCommandAsync(CancellationToken) Method¶
Sends the global failsafe command (§8.2: COB-ID 001h, DLC 0). Requires
Operational, and sets 1300h to 1 (EN 50325-5:2010 §6.4.2.1). The returned task is the send itself, not the node's
actor turn that started it: it completes when the bus service confirmed the send — on its
echo path once the echo arrived, otherwise once the driver accepted the frame — or reported
its failure (on
BackgroundExceptionOccurred, as for every frame), or when the send was cancelled.
The send carries cancellationToken linked with the token of the
Operational period: leaving Operational or disposing the node ends a send that has not
reached the bus service's driver call quietly, the caller's cancellation ends it with
OperationCanceledException; a frame the driver has been handed goes out (#294).
System.Threading.Tasks.Task SendGlobalFailsafeCommandAsync(System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
Parameters¶
cancellationToken CancellationToken
Returns¶
Exceptions¶
InvalidOperationException
The node is not Operational.
OperationCanceledException
cancellationToken was
cancelled before the send was confirmed; or the bus service was disposed under the send,
which is also reported on BackgroundExceptionOccurred as a transport failure.
CanOpenTransportException
LSS bit-rate switching suppresses transmission
of the GFC; the command was not handed to the driver.
ICanOpenSafety.TriggerSrdoAsync(int, CancellationToken) Method¶
Transmits producer srdoNumber now (§8.1, event-driven) and restarts its refresh cycle. Nothing happens outside Operational.
System.Threading.Tasks.Task TriggerSrdoAsync(int srdoNumber, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
Parameters¶
srdoNumber Int32
cancellationToken CancellationToken
Returns¶
ICanOpenSafety.VerifyPeerSafetyConfigurationAsync(byte, PeerSafetyConfiguration, CancellationToken) Method¶
§8.3.1 step D: uploads 13FEh (must be A5h), 13FFh:n of every expected SRDO (must equal the checksum of the expected record) and the records themselves, and compares. An SRDO the expectation does not name must be deleted; its checksum is not compared, because the device checks only those of existing SRDOs (§9.5). A tx SRDO whose record the bound description declares without a writable sub-index 3 is expected at an SRVT of 20 ms, and a peer that aborts the upload of a sub-index 3 the description does not declare with 0609 0011h does not implement it, which is no difference (CiA 319 §6.2). 13FFh:00, the checksums of the SRDOs expected and 13FEh pass the peer-SDO gate before the first frame. The identity of CiA 319 §5.2 is not read: it belongs to the configuration, and a DCF bound for the boot-up is bound for that node-id. Nothing is written. The peer's SDO channel is reserved for the whole transaction: it waits for a call to that peer already in flight, and a concurrent SDO call of this node to that peer is refused as already in flight. The transaction works from the description and the expectation as they were when it started — when it owns the peer's channel (the gate of every transfer and the comparison use copies taken then): a rebind, an unbind or an edit in place of the bound description, or a change to expected, after that takes effect for the next call.
System.Threading.Tasks.Task<CanKit.Pro.CANopen.Safety.PeerSafetyResult> VerifyPeerSafetyConfigurationAsync(byte peerNodeId, CanKit.Pro.CANopen.Safety.PeerSafetyConfiguration expected, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
Parameters¶
peerNodeId Byte
expected PeerSafetyConfiguration
cancellationToken CancellationToken
Returns¶
Exceptions¶
InvalidOperationException
The peer's 13FFh:00 is not exactly one byte
(it is UNSIGNED8; none, two or four bytes are refused, a longer one is not cut to its low
byte), or the count is above 64 (§8.4.2.2) or above the bound description's highest SRDO
record (the gate implies no record above it, so the SRDOs the peer has beyond the file
could not be verified) — refused before any further frame.
PeerSdoAccessException
The bound description does not declare 13FFh:00,
13FFh:n of an SRDO expected, or 13FEh — refused before the first frame; or, once the count
is read, sub-index 01h of a record up to it — refused before any further frame.
ArgumentException
The expectation names an SRDO above the peer's count,
or gives a tx SRDO whose record the description declares without a writable sub-index 3 an
SRVT other than 20 ms (CiA 319 §6.2); the parameter named is expected.
Events¶
ICanOpenSafety.GlobalFailsafeCommandReceived Event¶
A GFC arrived while Operational, whatever 1300h held; the node set it to 1 (including the node's own, on a bus that echoes).
Event Type¶
EventHandler<GlobalFailsafeCommandReceivedEventArgs>
ICanOpenSafety.SrdoReceived Event¶
A consumer SRDO received a valid pair and wrote it to the mapped objects.
Event Type¶
EventHandler<SrdoReceivedEventArgs>
ICanOpenSafety.SrdoStateChanged Event¶
An SRDO became valid or invalid (transitions only; never dropped).