An EtherCAT MainDevice written in Rust.
Unreleased - ReleaseDate
- #246 Windows:
tx_rx_task
is replaced withtx_rx_task_blocking
which is no longerasync
. It must be spawned into its own thread instead of an async task.tx_rx_task
will be removed in a future release.
- #234 Added
SubDeviceRef::sdo_write_array
to more cleanly write multiple SDO sub-indices and prevent mistakes. - #239 Add
MailboxError::Emergency { error_code, error_register }
variant to surface EMERGENCY responses from CoE transactions. - #246 Windows: Add
tx_rx_task_blocking
to use in a separate thread to send/receive EitherCAT frames. - #242 Add support for PDIs longer than a single PDU
- (breaking) #230 Increase MSRV from 1.77 to 1.79.
- #231 Enable reading of up to 64 PDO entries per PDO from EEPROM.
- #232 Use string index from EEPROM to read device name instead of hard coding to the first string index.
- #232 Add
{SubDevice,SubDeviceRef}::description()
method to get longer device name - #237 Read SubDevice group status in chunks of 16 devices to speed up group status reads.
- #239 Mailbox emergency responses now return
Error::Mailbox(MailboxError::Emergency)
instead of being ignored. - #238 Group SubDevice status checks are now chunked into however many fit into a frame, instead of being sent separately.
- #241 (@david-boles) During init, SMs and FMMUs are reset one-by-one instead of the entire block being written to.
- (breaking) #246
PduRx::receive_frame
now returnsResult<ReceiveAction, Error>
instead ofResult<(), Error>
.
- #229 Fix overflowing subtraction panic when calculating DC cycle offset.
0.5.0 - 2024-07-28
-
#216 PDU retries now use the same PDU index instead of allocating a new frame for every resend.
-
#217 EEPROM strings must now be valid ASCII as per the EtherCAT specification. UTF-8 strings will return an error when read.
-
(breaking) #218 Removed
expected
andgot
fields fromError::Wire(WireError::{Read,Write}BufferTooShort)
. -
(breaking) #218 Increase MSRV from 1.75 to 1.77.
-
(breaking) #227 Renamed many public items to use the newer EtherCAT terminology
MainDevice
andSubDevice
for master/slave respectively.Type Old New enum
SlaveState
SubDeviceState
fn
Client::num_slaves()
MainDevice::num_subdevices()
fn
Ds402::slave()
Ds402::subdevice()
fn
SlaveGroup::slave()
SubDeviceGroup::subdevice()
mod
ethercrab::slave_group
ethercrab::subdevice_group
struct
Client
MainDevice
struct
ClientConfig
MainDeviceConfig
struct
GroupSlaveIterator
GroupSubDeviceIterator
struct
Slave
SubDevice
struct
SlaveGroup
SubDeviceGroup
struct
SlaveGroupRef
SubDeviceGroupRef
struct
SlaveIdentity
SubDeviceIdentity
struct
SlavePdi
SubDevicePdi
struct
SlaveRef
SubDeviceRef
variant
AlStatusCode::SlaveNeedsColdStart
AlStatusCode::SubDeviceNeedsColdStart
variant
AlStatusCode::SlaveNeedsInit
AlStatusCode::SubDeviceNeedsInit
variant
AlStatusCode::SlaveNeedsPreop
AlStatusCode::SubDeviceNeedsPreop
variant
AlStatusCode::SlaveNeedsRestartedLocally
AlStatusCode::SubDeviceNeedsRestartedLocally
variant
AlStatusCode::SlaveNeedsSafeop
AlStatusCode::SubDeviceNeedsSafeop
variant
Error::UnknownSlave
Error::UnknownSubDevice
- #162 Add support for FreeBSD and NetBSD using BPF.
- #236 Change mailbox response validation to check index/subindex instead of returned counter.
0.4.3 - 2024-09-26
- #236 Change mailbox response validation to check index/subindex instead of returned counter.
0.4.2 - 2024-05-27
- #213 (@jbbjarnason) Add
alias_address
method toSlave
andSlaveRef
to get a SubDevice's alias address.
0.4.1 - 2024-04-05
- #208 Expose
DcSupport
enum at the crate root so it can be used by everyone.
0.4.0 - 2024-03-31
-
(breaking) #134 Bump MSRV to 1.75.0
-
#134 Refactor sub device EEPROM reader to be more efficient when skipping sections of the device EEPROM map.
-
(breaking) #142 Remove
PduRead
andPduData
traits. These are replaced withEtherCrabWireRead
andEtherCrabWireReadWrite
traits respectively, along withEtherCrabWireReadWrite
for write-only items.Some pertinent trait bounds changes in the public API:
SlaveRef::sdo_read
fromPduData
toEtherCrabWireWrite
SlaveRef::sdo_write
fromPduData
toEtherCrabWireReadSized
SlaveRef::register_read
fromPduData
toEtherCrabWireWrite
SlaveRef::register_write
fromPduData
toEtherCrabWireReadWrite
-
(breaking) #144
PduError::InvalidIndex(usize)
is now aPduError::InvalidIndex(u8)
as the EtherCAT index field is itself onl au8
. -
#151 Reduced overhead for EEPROM reads. Each chunk reader now only checks for and (attempt to) clear device errors once before reading a chunk of data, not for every chunk.
-
#156 Update
embassy-time
from 0.2.0 to 0.3.0. -
#181
PduStorage
now stores complete Ethernet frames instead of building them on the fly. This adds a little more overhead to each slot, so the reserved data const parameter must be larger to compensate. Use the newPduStorage::element_size
method to calculate element sizes based on a given maximum PDU payload value.
-
#141 Added the
ethercat-wire
andethercat-wire-derive
crates.These crates are EXPERIMENTAL. They may be improved for public use in the future but are currently designed around EtherCrab's internal needs and may be rough and/or buggy. Use with caution, and expect breaking changes.
-
#141 Re-export the following traits from
ethercrab-wire
for dealing with packing/unpacking data:EtherCrabWireRead
EtherCrabWireReadSized
EtherCrabWireReadWrite
EtherCrabWireSized
EtherCrabWireWrite
-
#151 Add
EepromError::ClearErrors
variant. -
#152 Expose
error::CoeAbortCode
for matching on CoE transfer errors. -
#169 Linux only: add
io_uring
-based blocking TX/RX loop for better performance. -
#173 Add MUSL libc support.
-
#178 Add
Error::SubDevice
to get a subdevice status code on failure. -
#180 Add
PreOpPdi
state, allowing access to a group's PDI whilst inPRE-OP
. -
#180 Add
ethercrab::std::ethercat_now
function to get the current time in nanoseconds from the EtherCAT epoch of 2000-01-01. -
#194 Added
SlaveGroup
methods to facilitate graceful shutdown:SlaveGroup<Op>::into_safe_op
SlaveGroup<SafeOp>::into_pre_op
SlaveGroup<PreOp>::into_init
The
ek1100
example shows these methods in use. -
#195 Add
Register::DcCyclicUnitControl
(0x0980). -
#193 Add
SlaveGroup::<PreOp>::request_into_op
to request all SubDevices in a group transition to OP, but does not wait for them to transition. Also addSlaveGroup::<Op>::all_op
to check if all SubDevices in the group have reached OP state. -
#198 Add
Error::DistributedClock(_)
andDistributedClockError
error variant and type to communicate DC errors. -
#198 Add
SlaveGroup::tx_rx_sync_system_time
,SlaveGroup::tx_rx_dc
,SlaveRef::set_dc_sync
andSlaveGroup::configure_dc_sync
to support EtherCAT Distributed Clocks.
- (breaking) (technically) #143 Fix typo
in name
AlStatusCode::ApplicationControllerAvailableI
->AlStatusCode::ApplicationControllerAvailable
- #152 CoE errors are not reported correctly
from
sdo_read
andsdo_write
. - #194
SlaveGroup<PreOp>::into_op
now transitions through SAFE-OP instead of illegally transitioning straight into OP.
- (breaking) #145 Remove the
context
field fromError::WorkingCounter
. The output from EtherCrab's error logging should be used instead. - (breaking) #181 Remove async
SendableFrame::send
. UseSendableFrame::send_blocking
instead. - #197 Remove
SlaveGroupState
trait. It is no longer required, but the same methods are available so migration should be as simple as just removing the import.
0.3.7 - 2024-03-12
- #183 Relax
'static
bound fortx_rx_task
on Windows.
0.3.6 - 2024-02-14
- #167 Add support for reading/writing
f32
,f64
andbool
. Note thatf64
cannot currently be written usingsdo_write
as only 4 byte expedited transfers are currently supported.
0.3.5 - 2023-12-22
-
#135 macOS only:
tx_rx_task
now uses native networking (BPF) instead oflibpcapng
to improve reliability. -
(breaking) #136 Fix unsoundness issue where
SlaveRef::io_raw
could be called multiple times, allowing multiple mutable references into the device's output data. -
(breaking) #136 Rename
SlaveRef::io_raw
toSlaveRef::io_raw_mut
.SlaveRef::io_raw
remains, but now only returns non-mutable references to both the device inputs and outputs.Also renames
SlaveRef::outputs_raw
toSlaveRef::outputs_raw_mut
.SlaveRef::outputs
now returns a non-mutable reference to the device output data.
0.3.4 - 2023-11-20
- #132 The mailbox counter is now per-device instead of global, fixing issues with many devices communicating over CoE.
- #132 Revert #130 "Counter in mailbox response is no longer checked." as this was masking the root cause, which is now fixed.
- (breaking) #132
Slave
no longer implementsClone
orPartialEq
. Devices should instead be compared usingname()
,identity()
,configured_address()
, etc.
0.3.3 - 2023-11-10
- #130 Counter in mailbox response is no longer checked.
0.3.2 - 2023-11-02
- #122 Added
Slave{Ref}::propagation_delay()
to get the EtherCAT propagation delay for a specific device on the network. - #126 Implement
PduRead
andPduData
for[u8; N]
.
- #121 Linux only: Relax
'static
lifetime requirement onstd::tx_rx_task
to a named lifetime to allow non-'static
storage to be used. - #124 Fixed some spurious panics from race conditions by using atomic wakers.
- #127 Improve frame allocation reliability when contention is high.
- (breaking) #124 Changed
PduTx::waker()
toPduTx::replace_waker()
. Instead of calling e.g.pdu_tx.waker().replace(ctx.waker().clone())
, now it should bepdu_tx.replace_waker(ctx.waker())
. - (potentially breaking) #125 Package upgrades, notably
async_io
andfutures_lite
from 1.x to 2.0.
0.3.1 - 2023-10-16
0.3.0 - 2023-10-12
-
#91 Add support for "cross" topologies, e.g. with EK1122.
-
#102 PDU retry behaviour is now configurable between no retries, a limited count, or retrying forever with the
RetryBehaviour
struct and associatedClientConfig.retry_behaviour
option. -
#103 Added optional
serde
feature to enable ser/de of some EtherCrab items. -
#104 Implement
std::error::Error
forethercrab::error::Error
when thestd
feature is enabled. -
#107 Add watchdog fields to
Register
enum:WatchdogDivider
,PdiWatchdog
SyncManagerWatchdog
,SyncManagerWatchdogStatus
SyncManagerWatchdogCounter
,PdiWatchdogCounter
. -
#113
SlaveState
now implementsPduRead
so can now be read directly, e.g.let (status, _wkc) = Command::fprd(slave.configured_address(), RegisterAddress::AlStatus.into()) .receive::<SlaveState>(&client) .await?;
- #92 If no slave devices are detected,
Client::init
will no longer exit with an error. - (breaking) #101
SendableFrame::send_blocking
andSendableFrame::send
must now return the number of bytes sent over the network. - (breaking) #101
SendableFrame::write_ethernet_packet
is no longerpub
. Instead, useSendableFrame::send_blocking
orSendableFrame::send
. - #103 Removed inner
smoltcp::error::Error
fromPduError::Ethernet
andPduError::CreateFrame
as these don't add much meaning to the variant. - (breaking) #109 Make all methods on
PduLoop
private. - (breaking) #113
Command::{code,address,parse}
are no longerpub
. - (breaking) #119 Changed
SlaveState::Unknown
toSlaveState::Other(u8)
to better represent unknown or different states of multiple slaves (e.g. when sending aBRD
).
- (breaking) #99 All PDU methods on
Client
(Client::bwr
,Client::fprd
) have been removed. Instead, use the same methods onCommand
likeCommand::bwr
,Command::fprd
etc.
0.2.1 - 2023-07-31
- #84
GroupSlave::iter
will now panic instead of completing early if a slave device is already borrowed. - #114 The
std
TX/RX future now consumes any queued packets, not just the first one. This fixes PDU timeout issues withzip
/join
ed futures.
- #83 Add
SlaveRef::identity
method to get the vendor ID, hardware revision, etc of a slave device. - #86 Expose the
SlaveIdentity
struct.
- #84 The
SlaveGroupState
trait is now not-doc-hidden so theGroupSlave::slave
method is more easily accessible.
0.2.0 - 2023-07-31
- #47 Add the ability to read/write registers/SDOs from grouped slave devices, with the methods
SlaveRef::register_read
,SlaveRef::register_write
,SlaveRef::sdo_read
andSlaveRef::sdo_write
. - #30 Added
Copy
,Clone
,PartialEq
andEq
implementations toError
andPduError
. - #1 Added
SlaveGroup::len
andSlaveGroup::is_empty
methods. - #29 Implement
Display
forError
,PduError
,MailboxError
,EepromError
,VisibleStringError
andPduValidationError
- (breaking) #31 Added a
ClientConfig
argument toClient::new
to allow configuration of various EtherCrab behaviours. - #55 Added
Client::init_single_group
to reduce boilerplate when only using a single group of devices. - #55 Removed MSRV commitment (was 1.68)
- #59 Added
SendableFrame::send_blocking
method.
- (breaking) #75
Client::request_slave_state
is removed. Groups should be transitioned into the various states individually usinginto_op
orinto_safe_op
. - (breaking) #75
SlaveGroup::new
is removed. Slave groups can be created withSlaveGroup::default()
instead - (breaking) #45 The
SlaveGroupContainer
trait is no longer needed and has been removed.
-
(breaking) #75
Client::init
no longer takes agroups
argument and now requiresG: Default
. -
(breaking) #75
SlaveGroup
s no longer configure using a closure - instead useSlaveGroup::iter
orSlaveGroup::slave
to configure slave devices inline. -
(breaking) #75
SlaveGroup
s now have a type state. Useinto_safe_op
andinto_op
to transition from PRE-OP as provided byClient::init
into run mode. -
#47 Slave
sdo_read
andsdo_write
methods no longer require the use ofSubIndex
. For single accesses, a rawu8
can be passed instead for cleaner configuration code. -
(breaking) #47
SlaveGroup::slave
andSlaveGroup::iter
(wasslaves
) now requires the passing of aClient
reference when called. -
(breaking) #47
SlaveGroup::slaves
is renamed toSlaveGroup::iter
-
(breaking) #47 Grouped slaves that were previously represented as
GroupSlave
s are now represented asSlaveRef<'_, SlavePdi<'_>>
instead.GroupSlave
is removed. -
(breaking) #47 The
io()
,inputs()
andoutputs()
methods on grouped slaves have been renamed toio_raw()
,inputs_raw()
andoutputs_raw()
respecitively. -
(breaking) #47 The
Slave.name
andSlave.identity
fields have been replaced with methods of the same name. -
(breaking) #45 The grouping closure passed to
Client::init
now requires a&dyn SlaveGroupHandle
to be returned. This is a sealed trait only implemented forSlaveGroup
s and allows some internal refactors by erasing the const generics fromSlaveGroup
. -
(breaking) #32 To mitigate some internal issues,
PduStorage
now requiresN
(the number of storage elements) to be a power of two. -
(breaking) #33
send_frames_blocking
is removed. It is replaced withPduTx::next_sendable_frame
which can be used to send any available frames in a loop until it returnsNone
. -
(breaking) #30 Removed
PduError::Encode
variant. -
(breaking) #25 Renamed
pdu_rx
toreceive_frame
to mirrorsend_frames_blocking
. -
(breaking) #20 Changed the way the client, tx and rx instances are initialised to only allow one TX and RX to exist.
Before
static PDU_STORAGE: PduStorage<MAX_FRAMES, MAX_PDU_DATA> = PduStorage::new(); static PDU_LOOP: PduLoop = PduLoop::new(PDU_STORAGE.as_ref()); async fn main_app(ex: &LocalExecutor<'static>) -> Result<(), Error> { let client = Arc::new(Client::new(&PDU_LOOP, Timeouts::default())); ex.spawn(tx_rx_task(INTERFACE, &client).unwrap()).detach(); }
After
static PDU_STORAGE: PduStorage<MAX_FRAMES, MAX_PDU_DATA> = PduStorage::new(); async fn main_app(ex: &LocalExecutor<'static>) -> Result<(), Error> { let (tx, rx, pdu_loop) = PDU_STORAGE.try_split().expect("can only split once"); let client = Arc::new(Client::new(pdu_loop, Timeouts::default())); ex.spawn(tx_rx_task(INTERFACE, tx, rx).unwrap()).detach(); }
-
(breaking) #16 Remove
TIMER
/TIMEOUT
generic parameter.std
environments will now use the timer provided bysmol
(async-io
).no_std
environments will useembassy-time
. -
(breaking) #9 Rename the fields of some variants in
ethercrab::error::Error
to make them less confusing. -
(breaking) #2 Rename
slave_group::Configurator
toSlaveGroupRef
. -
(breaking) #1
SlaveGroup::slaves
now returns an iterator over each slave with IO in the group, instead of a plain slave.
- #28 Fix abort code parsing for expedited SDO responses.
- #26 🎉 EtherCrab now works on stable Rust. The MSRV is 1.68.
- #23 Strip trailing null bytes (
\0
) in strings read from SII - #14 Fixed various overflow/arithmetic bugs in distributed clock time calculations and PDI configuration
- #6 Fixed topology detection not stopping at first upstream fork when there is a slave device before the fork.
- #6 Internal bugfixes to topology discovery code.
- #2 Fixed multiple group PDI mapping calculation during initialisation.
- [#57] Fixed a buffer size calculation crash when reading SDOs.
0.1.0 - 2023-01-02
- Initial release