# Changelog A pure Rust EtherCAT MainDevice supporting std and no_std environments. ## [Unreleased] - ReleaseDate ## [0.7.1] - 2026-03-23 ### Fixed - [#366](https://github.com/ethercrab-rs/ethercrab/pull/366) Publicly expose `DefaultLock` so crate consumers can use it. ### Changed - [#365](https://github.com/ethercrab-rs/ethercrab/pull/365) (@Dirreke) Add `io-uring` feature so `io_uring` can be disabled for Linux platforms that don't support it. Example `Cargo.toml`: ```toml ethercrab = { version = "0.8.0", default-features = false, features = [ "std" ] } ``` ## [0.7.0] - 2026-03-16 ### Fixed - [#315](https://github.com/ethercrab-rs/ethercrab/pull/315) (@ClarkZaitun) Read SubDevice status code from correct register when state transition fails. - [#313](https://github.com/ethercrab-rs/ethercrab/pull/313) (@fpdotmonkey) Read actual CoE abort code instead of returning `CoeAbortCode::Incompatible` on SDO transfer failures. - [#322](https://github.com/ethercrab-rs/ethercrab/pull/322) Set all configured addresses before initialising SubDevices, fixing an error when adding an existing powered on segment to the EtherCAT network. - [#322](https://github.com/ethercrab-rs/ethercrab/pull/322) Use the same DC reference time to set SYNC0 start time, fixing offsets in SubDevices with 32 bit clocks. ### Added - [#310](https://github.com/ethercrab-rs/ethercrab/pull/310) Add support for XDP on Linux systems using the `xdp` feature. - [#305](https://github.com/ethercrab-rs/ethercrab/pull/305) (@fpdotmonkey) Added `SubDevice::sdo_info_object_description_list` and `SubDevice::sdo_info_object_quantities` to get information about a SubDevice's SDOs. - [#351](https://github.com/ethercrab-rs/ethercrab/pull/351) Added basic oversampling support with `SubDevice::set_oversampling`. ### Changed - [#298](https://github.com/ethercrab-rs/ethercrab/pull/298) **(breaking)** Change MSRV from 1.81 to 1.85, migrate to edition 2024. - [#331](https://github.com/ethercrab-rs/ethercrab/pull/331) **(breaking)** (@theol0403) Use `lock_api` traits to allow for different locking behaviour. - [#301](https://github.com/ethercrab-rs/ethercrab/pull/301) No longer warn when mailbox counter is not what was sent by the MainDevice. - [#320](https://github.com/ethercrab-rs/ethercrab/pull/320) **(breaking)** (@fpdotmonkey) Add `TimeoutError` to `Error::Timeout` to give a reason why a timeout occurred. - [#328](https://github.com/ethercrab-rs/ethercrab/pull/328) **(breaking)** (@theol0403) Change `MainDevice::init` to require an empty groups structure to be passed in, instead of relying on a `Default` trait bound. - [#330](https://github.com/ethercrab-rs/ethercrab/pull/330) (@theol0403) Stop re-reading potentially broken SyncManager types over CoE. Now the EEPROM is the source of truth for this information. - [#354](https://github.com/ethercrab-rs/ethercrab/pull/354) (@prrn) Don't enable Sync Managers with a length of zero. - [#347](https://github.com/ethercrab-rs/ethercrab/pull/347) (@fpdotmonkey) Stop writing to register `0x0980`. The prior behaviour was copied from SOEM. The register has very little documentation about it and causes issues with some ABB drives, so any writes to it within EtherCrab are removed. ## [0.6.0] - 2025-03-29 ### Added - [#234](https://github.com/ethercrab-rs/ethercrab/pull/234) Added `SubDeviceRef::sdo_write_array` to more cleanly write multiple SDO sub-indices and prevent mistakes. - [#274](https://github.com/ethercrab-rs/ethercrab/pull/274) (@1cedsoda) Added `SubDeviceRef::sdo_read_array` to read all sub-indices from a given SDO. - [#239](https://github.com/ethercrab-rs/ethercrab/pull/239) Add `MailboxError::Emergency { error_code, error_register }` variant to surface EMERGENCY responses from CoE transactions. - [#246](https://github.com/ethercrab-rs/ethercrab/pull/246) **Windows:** Add `tx_rx_task_blocking` to use in a separate thread to send/receive EitherCAT frames. - [#242](https://github.com/ethercrab-rs/ethercrab/pull/242) Add support for PDIs longer than a single PDU - [#269](https://github.com/ethercrab-rs/ethercrab/pull/269) **(breaking)** `SubDeviceGroup::tx_rx_*` methods now read the state (PRE-OP, OP, etc) of each SubDevice in the group, along with methods on `TxRxResponse` to test for various state conditions. - [#273](https://github.com/ethercrab-rs/ethercrab/pull/273) Added `SubDevice::set_alias_address` and `SubDeviceRef::set_alias_address` to write an alias address to a SubDevice's EEPROM. - [#278](https://github.com/ethercrab-rs/ethercrab/pull/278) Add `SubDevice::{eeprom_read, eeprom_read_raw, eeprom_size, eeprom_write_dangerously}` methods for working with a SubDevice's EEPROM. ### Removed - [#260](https://github.com/ethercrab-rs/ethercrab/pull/260) **(breaking)** The `PduError::NoWaker` variant has been removed as it is no longer used or returned by any EtherCrab method. - [#263](https://github.com/ethercrab-rs/ethercrab/pull/263) **(breaking)** `SubDeviceIterator` is removed. The returned iterator's type signature is now `impl Iterator>` - [#270](https://github.com/ethercrab-rs/ethercrab/pull/270) **(breaking)** **Windows:** `tx_rx_task` is removed and replaced with `tx_rx_task_blocking` which is no longer `async`. It must be spawned into its own thread instead of an async task. ### Changed - [#263](https://github.com/ethercrab-rs/ethercrab/pull/263) `SubDeviceGroup` now wraps its PDI storage in an internal spinlock to allow easier use across multiple tasks/threads, at the risk of introducing deadlocks. - [#263](https://github.com/ethercrab-rs/ethercrab/pull/263) Remove `Error::Borrow` as it's no longer returned from any EtherCrab method. - [#287](https://github.com/ethercrab-rs/ethercrab/pull/287) **(breaking)** Increase MSRV from 1.77 to 1.81. - [#231](https://github.com/ethercrab-rs/ethercrab/pull/231) Enable reading of up to 64 PDO entries per PDO from EEPROM. - [#232](https://github.com/ethercrab-rs/ethercrab/pull/232) Use string index from EEPROM to read device name instead of hard coding to the first string index. - [#232](https://github.com/ethercrab-rs/ethercrab/pull/232) Add `{SubDevice,SubDeviceRef}::description()` method to get longer device name - [#237](https://github.com/ethercrab-rs/ethercrab/pull/237) Read SubDevice group status in chunks of 16 devices to speed up group status reads. - [#239](https://github.com/ethercrab-rs/ethercrab/pull/239) Mailbox emergency responses now return `Error::Mailbox(MailboxError::Emergency)` instead of being ignored. - [#238](https://github.com/ethercrab-rs/ethercrab/pull/238) Group SubDevice status checks are now chunked into however many fit into a frame, instead of being sent separately. - [#241](https://github.com/ethercrab-rs/ethercrab/pull/241) (@david-boles) During init, SMs and FMMUs are reset one-by-one instead of the entire block being written to. - [#246](https://github.com/ethercrab-rs/ethercrab/pull/246) **(breaking)** `PduRx::receive_frame` now returns `Result` instead of `Result<(), Error>`. - [#269](https://github.com/ethercrab-rs/ethercrab/pull/269) **(breaking)** `SubDeviceGroup::tx_rx_*` methods now return a `TxRxResponse` struct instead of a tuple. - [#278](https://github.com/ethercrab-rs/ethercrab/pull/278) Add `Deref` and `DerefMut` impls for `SubDeviceRef` instead of copy/pasting methods from `SubDevice`. - [#287](https://github.com/ethercrab-rs/ethercrab/pull/287) Change SM FMMU mapping fallback behaviour to use the current SM's index instead of looking for the first FMMU of the correct direction. ### Fixed - [#229](https://github.com/ethercrab-rs/ethercrab/pull/229) Fix overflowing subtraction panic when calculating DC cycle offset. - [#260](https://github.com/ethercrab-rs/ethercrab/pull/260) Frames received before their future's waker is registered will no longer trigger a `NoWaker` error. ## [0.5.6] - 2025-03-28 ### Fixed - [#294](https://github.com/ethercrab-rs/ethercrab/pull/294) Compute SM type using fallback data when EEPROM record is incomplete. ## [0.5.5] - 2025-03-21 ### Fixed - [#291](https://github.com/ethercrab-rs/ethercrab/pull/291) Allow initialisation to progress further for devices with empty EEPROMs by falling back to defaults if config data cannot be found. ## [0.5.4] - 2025-03-20 ### Fixed - [#288](https://github.com/ethercrab-rs/ethercrab/pull/288) Prevent overflow and infinite loops when reading empty or nearly-empty SubDevice EEPROMs. ## [0.5.3] - 2025-01-24 ### Added - [#242](https://github.com/ethercrab-rs/ethercrab/pull/242) Add support for PDIs longer than a single PDU ## [0.5.2] - 2024-12-21 ### Removed - [#260](https://github.com/ethercrab-rs/ethercrab/pull/260) **(breaking)** The `PduError::NoWaker` variant has been removed as it is no longer used or returned by any EtherCrab method. ### Fixed - [#260](https://github.com/ethercrab-rs/ethercrab/pull/260) Frames received before their future's waker is registered will no longer trigger a `NoWaker` error. ## [0.5.1] - 2024-11-26 ### Deprecated - [#248](https://github.com/ethercrab-rs/ethercrab/pull/248) **Windows:** `tx_rx_task` is replaced with `tx_rx_task_blocking` which is no longer `async`. It must be spawned into its own thread instead of an async task. `tx_rx_task` will be removed in a future release. ### Added - [#248](https://github.com/ethercrab-rs/ethercrab/pull/248) **Windows:** Add `tx_rx_task_blocking` to use in a separate thread to send/receive EitherCAT frames. ### Changed - [#248](https://github.com/ethercrab-rs/ethercrab/pull/248) **(breaking)** `PduRx::receive_frame` now returns `Result` instead of `Result<(), Error>`. ## [0.5.0] - 2024-07-28 ### Changed - [#216](https://github.com/ethercrab-rs/ethercrab/pull/216) PDU retries now use the same PDU index instead of allocating a new frame for every resend. - [#217](https://github.com/ethercrab-rs/ethercrab/pull/217) EEPROM strings must now be valid ASCII as per the EtherCAT specification. UTF-8 strings will return an error when read. - [#218](https://github.com/ethercrab-rs/ethercrab/pull/218) **(breaking)** Removed `expected` and `got` fields from `Error::Wire(WireError::{Read,Write}BufferTooShort)`. - [#218](https://github.com/ethercrab-rs/ethercrab/pull/218) **(breaking)** Increase MSRV from 1.75 to 1.77. - [#227](https://github.com/ethercrab-rs/ethercrab/pull/227) **(breaking)** Renamed many public items to use the newer EtherCAT terminology `MainDevice` and `SubDevice` 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` | ### Added - [#162](https://github.com/ethercrab-rs/ethercrab/pull/162) Add support for FreeBSD and NetBSD using BPF. ### Changed - [#236](https://github.com/ethercrab-rs/ethercrab/pull/236) Change mailbox response validation to check index/subindex instead of returned counter. ## [0.4.3] - 2024-09-26 ### Changed - [#236](https://github.com/ethercrab-rs/ethercrab/pull/236) Change mailbox response validation to check index/subindex instead of returned counter. ## [0.4.2] - 2024-05-27 ### Added - [#213](https://github.com/ethercrab-rs/ethercrab/pull/213) (@jbbjarnason) Add `alias_address` method to `Slave` and `SlaveRef` to get a SubDevice's alias address. ## [0.4.1] - 2024-04-05 ### Fixed - [#208](https://github.com/ethercrab-rs/ethercrab/pull/208) Expose `DcSupport` enum at the crate root so it can be used by everyone. ## [0.4.0] - 2024-03-31 ### Changed - [#134](https://github.com/ethercrab-rs/ethercrab/pull/134) **(breaking)** Bump MSRV to 1.75.0 - [#134](https://github.com/ethercrab-rs/ethercrab/pull/134) Refactor sub device EEPROM reader to be more efficient when skipping sections of the device EEPROM map. - [#142](https://github.com/ethercrab-rs/ethercrab/pull/142) **(breaking)** Remove `PduRead` and `PduData` traits. These are replaced with `EtherCrabWireRead` and `EtherCrabWireReadWrite` traits respectively, along with `EtherCrabWireReadWrite` for write-only items. Some pertinent trait bounds changes in the public API: - `SlaveRef::sdo_read` from `PduData` to `EtherCrabWireWrite` - `SlaveRef::sdo_write` from `PduData` to `EtherCrabWireReadSized` - `SlaveRef::register_read` from `PduData` to `EtherCrabWireWrite` - `SlaveRef::register_write` from `PduData` to `EtherCrabWireReadWrite` - [#144](https://github.com/ethercrab-rs/ethercrab/pull/144) **(breaking)** `PduError::InvalidIndex(usize)` is now a `PduError::InvalidIndex(u8)` as the EtherCAT index field is itself onl a `u8`. - [#151](https://github.com/ethercrab-rs/ethercrab/pull/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](https://github.com/ethercrab-rs/ethercrab/pull/156) Update `embassy-time` from 0.2.0 to 0.3.0. - [#181](https://github.com/ethercrab-rs/ethercrab/pull/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 new `PduStorage::element_size` method to calculate element sizes based on a given maximum PDU payload value. ### Added - [#141](https://github.com/ethercrab-rs/ethercrab/pull/141) Added the `ethercat-wire` and `ethercat-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](https://github.com/ethercrab-rs/ethercrab/pull/141) Re-export the following traits from `ethercrab-wire` for dealing with packing/unpacking data: - `EtherCrabWireRead` - `EtherCrabWireReadSized` - `EtherCrabWireReadWrite` - `EtherCrabWireSized` - `EtherCrabWireWrite` - [#151](https://github.com/ethercrab-rs/ethercrab/pull/151) Add `EepromError::ClearErrors` variant. - [#152](https://github.com/ethercrab-rs/ethercrab/pull/152) Expose `error::CoeAbortCode` for matching on CoE transfer errors. - [#169](https://github.com/ethercrab-rs/ethercrab/pull/169) Linux only: add `io_uring`-based blocking TX/RX loop for better performance. - [#173](https://github.com/ethercrab-rs/ethercrab/pull/173) Add MUSL libc support. - [#178](https://github.com/ethercrab-rs/ethercrab/pull/178) Add `Error::SubDevice` to get a subdevice status code on failure. - [#180](https://github.com/ethercrab-rs/ethercrab/pull/#180) Add `PreOpPdi` state, allowing access to a group's PDI whilst in `PRE-OP`. - [#180](https://github.com/ethercrab-rs/ethercrab/pull/#180) Add `ethercrab::std::ethercat_now` function to get the current time in nanoseconds from the EtherCAT epoch of 2000-01-01. - [#194](https://github.com/ethercrab-rs/ethercrab/pull/#194) Added `SlaveGroup` methods to facilitate graceful shutdown: - `SlaveGroup::into_safe_op` - `SlaveGroup::into_pre_op` - `SlaveGroup::into_init` The `ek1100` example shows these methods in use. - [#195](https://github.com/ethercrab-rs/ethercrab/pull/#195) Add `Register::DcCyclicUnitControl` (0x0980). - [#193](https://github.com/ethercrab-rs/ethercrab/pull/#193) Add `SlaveGroup::::request_into_op` to request all SubDevices in a group transition to OP, but does not wait for them to transition. Also add `SlaveGroup::::all_op` to check if all SubDevices in the group have reached OP state. - [#198](https://github.com/ethercrab-rs/ethercrab/pull/#198) Add `Error::DistributedClock(_)` and `DistributedClockError` error variant and type to communicate DC errors. - [#198](https://github.com/ethercrab-rs/ethercrab/pull/#198) Add `SlaveGroup::tx_rx_sync_system_time`, `SlaveGroup::tx_rx_dc`, `SlaveRef::set_dc_sync` and `SlaveGroup::configure_dc_sync` to support EtherCAT Distributed Clocks. ### Fixed - [#143](https://github.com/ethercrab-rs/ethercrab/pull/143) **(breaking)** (technically) Fix typo in name `AlStatusCode::ApplicationControllerAvailableI` -> `AlStatusCode::ApplicationControllerAvailable` - [#152](https://github.com/ethercrab-rs/ethercrab/pull/152) CoE errors are not reported correctly from `sdo_read` and `sdo_write`. - [#194](https://github.com/ethercrab-rs/ethercrab/pull/194) `SlaveGroup::into_op` now transitions through SAFE-OP instead of illegally transitioning straight into OP. ### Removed - [#145](https://github.com/ethercrab-rs/ethercrab/pull/145) **(breaking)** Remove the `context` field from `Error::WorkingCounter`. The output from EtherCrab's error logging should be used instead. - [#181](https://github.com/ethercrab-rs/ethercrab/pull/181) **(breaking)** Remove async `SendableFrame::send`. Use `SendableFrame::send_blocking` instead. - [#197](https://github.com/ethercrab-rs/ethercrab/pull/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 ### Fixed - [#183](https://github.com/ethercrab-rs/ethercrab/pull/183) Relax `'static` bound for `tx_rx_task` on Windows. ## [0.3.6] - 2024-02-14 ### Added - [#167](https://github.com/ethercrab-rs/ethercrab/pull/167) Add support for reading/writing `f32`, `f64` and `bool`. Note that `f64` cannot currently be written using `sdo_write` as only 4 byte expedited transfers are currently supported. ## [0.3.5] - 2023-12-22 ### Changed - [#135](https://github.com/ethercrab-rs/ethercrab/pull/135) macOS only: `tx_rx_task` now uses native networking (BPF) instead of `libpcapng` to improve reliability. - [#136](https://github.com/ethercrab-rs/ethercrab/pull/136) **(breaking)** Fix unsoundness issue where `SlaveRef::io_raw` could be called multiple times, allowing multiple mutable references into the device's output data. - [#136](https://github.com/ethercrab-rs/ethercrab/pull/136) **(breaking)** Rename `SlaveRef::io_raw` to `SlaveRef::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` to `SlaveRef::outputs_raw_mut`. `SlaveRef::outputs` now returns a non-mutable reference to the device output data. ## [0.3.4] - 2023-11-20 ### Fixed - [#132](https://github.com/ethercrab-rs/ethercrab/pull/132) The mailbox counter is now per-device instead of global, fixing issues with many devices communicating over CoE. ### Changed - [#132](https://github.com/ethercrab-rs/ethercrab/pull/132) Revert [#130](https://github.com/ethercrab-rs/ethercrab/pull/130) "Counter in mailbox response is no longer checked." as this was masking the root cause, which is now fixed. - [#132](https://github.com/ethercrab-rs/ethercrab/pull/132) **(breaking)** `Slave` no longer implements `Clone` or `PartialEq`. Devices should instead be compared using `name()`, `identity()`, `configured_address()`, etc. ## [0.3.3] - 2023-11-10 ### Changed - [#130](https://github.com/ethercrab-rs/ethercrab/pull/130) Counter in mailbox response is no longer checked. ## [0.3.2] - 2023-11-02 ### Added - [#122] Added `Slave{Ref}::propagation_delay()` to get the EtherCAT propagation delay for a specific device on the network. - [#126] Implement `PduRead` and `PduData` for `[u8; N]`. ### Fixed - [#121] **Linux only:** Relax `'static` lifetime requirement on `std::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. ### Changed - [#124] **(breaking)** Changed `PduTx::waker()` to `PduTx::replace_waker()`. Instead of calling e.g. `pdu_tx.waker().replace(ctx.waker().clone())`, now it should be `pdu_tx.replace_waker(ctx.waker())`. - (potentially breaking) [#125] Package upgrades, notably `async_io` and `futures_lite` from 1.x to 2.0. ## [0.3.1] - 2023-10-16 ## [0.3.0] - 2023-10-12 ### Added - [#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 associated `ClientConfig.retry_behaviour` option. - [#103] Added optional `serde` feature to enable ser/de of some EtherCrab items. - [#104] Implement `std::error::Error` for `ethercrab::error::Error` when the `std` feature is enabled. - [#107] Add watchdog fields to `Register` enum: `WatchdogDivider`, `PdiWatchdog` `SyncManagerWatchdog`, `SyncManagerWatchdogStatus` `SyncManagerWatchdogCounter`, `PdiWatchdogCounter`. - [#113] `SlaveState` now implements `PduRead` so can now be read directly, e.g. ```rust let (status, _wkc) = Command::fprd(slave.configured_address(), RegisterAddress::AlStatus.into()) .receive::(&client) .await?; ``` ### Changed - [#92] If no slave devices are detected, `Client::init` will no longer exit with an error. - [#101] **(breaking)** `SendableFrame::send_blocking` and `SendableFrame::send` must now return the number of bytes sent over the network. - [#101] **(breaking)** `SendableFrame::write_ethernet_packet` is no longer `pub`. Instead, use `SendableFrame::send_blocking` or `SendableFrame::send`. - [#103] Removed inner `smoltcp::error::Error` from `PduError::Ethernet` and `PduError::CreateFrame` as these don't add much meaning to the variant. - [#109] **(breaking)** Make all methods on `PduLoop` private. - [#113] **(breaking)** `Command::{code,address,parse}` are no longer `pub`. - [#119] **(breaking)** Changed `SlaveState::Unknown` to `SlaveState::Other(u8)` to better represent unknown or different states of multiple slaves (e.g. when sending a `BRD`). ### Removed - [#99] **(breaking)** All PDU methods on `Client` (`Client::bwr`, `Client::fprd`) have been removed. Instead, use the same methods on `Command` like `Command::bwr`, `Command::fprd` etc. ## [0.2.1] - 2023-07-31 ### Fixed - [#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 with `zip`/`join`ed futures. ### Added - [#83] Add `SlaveRef::identity` method to get the vendor ID, hardware revision, etc of a slave device. - [#86] Expose the `SlaveIdentity` struct. ### Changed - [#84] The `SlaveGroupState` trait is now not-doc-hidden so the `GroupSlave::slave` method is more easily accessible. ## [0.2.0] - 2023-07-31 ### Added - [#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` and `SlaveRef::sdo_write`. - [#30] Added `Copy`, `Clone`, `PartialEq` and `Eq` implementations to `Error` and `PduError`. - [#1] Added `SlaveGroup::len` and `SlaveGroup::is_empty` methods. - [#29] Implement `Display` for `Error`, `PduError`, `MailboxError`, `EepromError`, `VisibleStringError` and `PduValidationError` - [#31] **(breaking)** Added a `ClientConfig` argument to `Client::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. ### Removed - [#75] **(breaking)** `Client::request_slave_state` is removed. Groups should be transitioned into the various states individually using `into_op` or `into_safe_op`. - [#75] **(breaking)** `SlaveGroup::new` is removed. Slave groups can be created with `SlaveGroup::default()` instead - [#45] **(breaking)** The `SlaveGroupContainer` trait is no longer needed and has been removed. ### Changed - [#75] **(breaking)** `Client::init` no longer takes a `groups` argument and now requires `G: Default`. - [#75] **(breaking)** `SlaveGroup`s no longer configure using a closure - instead use `SlaveGroup::iter` or `SlaveGroup::slave` to configure slave devices inline. - [#75] **(breaking)** `SlaveGroup`s now have a type state. Use `into_safe_op` and `into_op` to transition from PRE-OP as provided by `Client::init` into run mode. - [#47] Slave `sdo_read` and `sdo_write` methods no longer require the use of `SubIndex`. For single accesses, a raw `u8` can be passed instead for cleaner configuration code. - [#47] **(breaking)** `SlaveGroup::slave` and `SlaveGroup::iter` (was `slaves`) now requires the passing of a `Client` reference when called. - [#47] **(breaking)** `SlaveGroup::slaves` is renamed to `SlaveGroup::iter` - [#47] **(breaking)** Grouped slaves that were previously represented as `GroupSlave`s are now represented as `SlaveRef<'_, SlavePdi<'_>>` instead. `GroupSlave` is removed. - [#47] **(breaking)** The `io()`, `inputs()` and `outputs()` methods on grouped slaves have been renamed to `io_raw()`, `inputs_raw()` and `outputs_raw()` respecitively. - [#47] **(breaking)** The `Slave.name` and `Slave.identity` fields have been replaced with methods of the same name. - [#45] **(breaking)** The grouping closure passed to `Client::init` now requires a `&dyn SlaveGroupHandle` to be returned. This is a sealed trait only implemented for `SlaveGroup`s and allows some internal refactors by erasing the const generics from `SlaveGroup`. - [#32] **(breaking)** To mitigate some internal issues, `PduStorage` now requires `N` (the number of storage elements) to be a power of two. - [#33] **(breaking)** `send_frames_blocking` is removed. It is replaced with `PduTx::next_sendable_frame` which can be used to send any available frames in a loop until it returns `None`. - [#30] **(breaking)** Removed `PduError::Encode` variant. - [#25] **(breaking)** Renamed `pdu_rx` to `receive_frame` to mirror `send_frames_blocking`. - [#20] **(breaking)** Changed the way the client, tx and rx instances are initialised to only allow one TX and RX to exist. Before ```rust static PDU_STORAGE: PduStorage = 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 ```rust static PDU_STORAGE: PduStorage = 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(); } ``` - [#16] **(breaking)** Remove `TIMER`/`TIMEOUT` generic parameter. `std` environments will now use the timer provided by `smol` (`async-io`). `no_std` environments will use `embassy-time`. - [#9] **(breaking)** Rename the fields of some variants in `ethercrab::error::Error` to make them less confusing. - [#2] **(breaking)** Rename `slave_group::Configurator` to `SlaveGroupRef`. - [#1] **(breaking)** `SlaveGroup::slaves` now returns an iterator over each slave with IO in the group, instead of a plain slave. ### Fixed - [#28] Fix abort code parsing for expedited SDO responses. - [#26] :tada: 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 ### Added - Initial release [unreleased]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.7.1...HEAD [0.7.1]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.7.0...ethercrab-v0.7.1 [0.7.0]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.6.0...ethercrab-v0.7.0 [0.6.0]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.5.6...ethercrab-v0.6.0 [0.5.6]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.5.5...ethercrab-v0.5.6 [0.5.5]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.5.4...ethercrab-v0.5.5 [0.5.4]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.5.3...ethercrab-v0.5.4 [0.5.3]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.5.2...ethercrab-v0.5.3 [0.5.2]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.5.1...ethercrab-v0.5.2 [0.5.1]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.5.0...ethercrab-v0.5.1 [0.5.0]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.4.2...ethercrab-v0.5.0 [0.4.3]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.4.2...ethercrab-v0.4.3 [0.4.2]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.4.1...ethercrab-v0.4.2 [0.4.1]: https://github.com/ethercrab-rs/ethercrab/compare/ethercrab-v0.4.0...ethercrab-v0.4.1 [0.4.0]: https://github.com/ethercrab-rs/ethercrab/compare/v0.3.6...ethercrab-v0.4.0 [0.3.7]: https://github.com/ethercrab-rs/ethercrab/compare/v0.3.6...v0.3.7 [0.3.6]: https://github.com/ethercrab-rs/ethercrab/compare/v0.3.5...v0.3.6 [0.3.5]: https://github.com/ethercrab-rs/ethercrab/compare/v0.3.4...v0.3.5 [0.3.4]: https://github.com/ethercrab-rs/ethercrab/compare/v0.3.3...v0.3.4 [0.3.3]: https://github.com/ethercrab-rs/ethercrab/compare/v0.3.2...v0.3.3 [0.3.4]: https://github.com/ethercrab-rs/ethercrab/compare/v0.3.2...v0.3.4 [0.3.2]: https://github.com/ethercrab-rs/ethercrab/compare/v0.3.0...v0.3.2 [0.3.1]: https://github.com/ethercrab-rs/ethercrab/compare/v0.3.0...v0.3.1 [0.3.0]: https://github.com/ethercrab-rs/ethercrab/compare/v0.2.1...v0.3.0 [0.2.1]: https://github.com/ethercrab-rs/ethercrab/compare/v0.2.0...v0.2.1 [#2]: https://github.com/ethercrab-rs/ethercrab/pull/2 [#1]: https://github.com/ethercrab-rs/ethercrab/pull/1 [#6]: https://github.com/ethercrab-rs/ethercrab/pull/6 [#9]: https://github.com/ethercrab-rs/ethercrab/pull/9 [#14]: https://github.com/ethercrab-rs/ethercrab/pull/14 [#16]: https://github.com/ethercrab-rs/ethercrab/pull/16 [#23]: https://github.com/ethercrab-rs/ethercrab/pull/23 [#20]: https://github.com/ethercrab-rs/ethercrab/pull/20 [#25]: https://github.com/ethercrab-rs/ethercrab/pull/25 [#26]: https://github.com/ethercrab-rs/ethercrab/pull/26 [#28]: https://github.com/ethercrab-rs/ethercrab/pull/28 [#29]: https://github.com/ethercrab-rs/ethercrab/pull/29 [#30]: https://github.com/ethercrab-rs/ethercrab/pull/30 [#31]: https://github.com/ethercrab-rs/ethercrab/pull/31 [#32]: https://github.com/ethercrab-rs/ethercrab/pull/32 [#33]: https://github.com/ethercrab-rs/ethercrab/pull/33 [#45]: https://github.com/ethercrab-rs/ethercrab/pull/45 [#47]: https://github.com/ethercrab-rs/ethercrab/pull/47 [#55]: https://github.com/ethercrab-rs/ethercrab/pull/55 [#59]: https://github.com/ethercrab-rs/ethercrab/pull/59 [#75]: https://github.com/ethercrab-rs/ethercrab/pull/75 [#83]: https://github.com/ethercrab-rs/ethercrab/pull/83 [#84]: https://github.com/ethercrab-rs/ethercrab/pull/84 [#86]: https://github.com/ethercrab-rs/ethercrab/pull/86 [#91]: https://github.com/ethercrab-rs/ethercrab/pull/91 [#92]: https://github.com/ethercrab-rs/ethercrab/pull/92 [#99]: https://github.com/ethercrab-rs/ethercrab/pull/99 [#101]: https://github.com/ethercrab-rs/ethercrab/pull/101 [#102]: https://github.com/ethercrab-rs/ethercrab/pull/102 [#103]: https://github.com/ethercrab-rs/ethercrab/pull/103 [#104]: https://github.com/ethercrab-rs/ethercrab/pull/104 [#107]: https://github.com/ethercrab-rs/ethercrab/pull/107 [#109]: https://github.com/ethercrab-rs/ethercrab/pull/109 [#113]: https://github.com/ethercrab-rs/ethercrab/pull/113 [#114]: https://github.com/ethercrab-rs/ethercrab/pull/114 [#119]: https://github.com/ethercrab-rs/ethercrab/pull/119 [#121]: https://github.com/ethercrab-rs/ethercrab/pull/121 [#122]: https://github.com/ethercrab-rs/ethercrab/pull/122 [#124]: https://github.com/ethercrab-rs/ethercrab/pull/124 [#125]: https://github.com/ethercrab-rs/ethercrab/pull/125 [#126]: https://github.com/ethercrab-rs/ethercrab/pull/126 [#127]: https://github.com/ethercrab-rs/ethercrab/pull/127 [0.2.0]: https://github.com/ethercrab-rs/ethercrab/compare/v0.1.0...v0.2.0 [0.1.0]: https://github.com/ethercrab-rs/ethercrab/compare/fb37346...v0.1.0