« Posts list

EtherCrab 0.7 Released

EtherCrab 0.7.0 (lib.rs) is out as the next release of this pure Rust EtherCAT MainDevice! There are some minor breaking changes, but nothing too difficult to migrate. Otherwise, not much to report as this is a release to get a couple of features out in the wild before some larger breaking changes in future EtherCrab versions. Full changelog is available here.

Breaking changes

There isn't too much in this release, so don't worry. First off, the Minimum Supported Rust Version (MSRV) has been bumped from 1.81 to 1.85, with a migration to Rust edition 2024 at the same time.

Next, an extra generic parameter has been added to SubDeviceGroup and related items such as PdiReadGuard. For example, this is how SubDeviceGroup has changed:

// EtherCrab 0.6
pub struct SubDeviceGroup<
    const MAX_SUBDEVICES: usize,
    const MAX_PDI: usize,
    S = PreOp,
    DC = NoDc,
>

// EtherCrab 0.7
pub struct SubDeviceGroup<
    const MAX_SUBDEVICES: usize,
    const MAX_PDI: usize,
    R: RawRwLock = crate::DefaultLock, // <-- NEW
    S = PreOp,
    DC = NoDc,
>

To mirror EtherCrab 0.6 behaviour by default, the field is set to a lock of spin::Yield for std, and spin::Spin for no_std, however this change allows the use of custom locks, as long as they implement the lock_api traits.

Another minor API breakage is in MainDevice::init. It now requires a default groups struct to be passed as an extra argument, instead of requiring G: Default and doing it internally. This should just be a one line change as there was already a Default bound on MainDevice::init:

#[derive(Default)]
struct Groups {
    /* snip */
}

let groups = maindevice
    .init::<MAX_SUBDEVICES, _>(
        ethercat_now,
        Groups::default(), // <-- NEW
        |groups: &Groups, subdevice| match subdevice.name() {
            "EL2889" | "EK1100" | "EK1501" => Ok(&groups.slow_outputs),
            "EL2828" => Ok(&groups.fast_outputs),
            _ => Err(Error::UnknownSubDevice),
        },
    )
    .await
    .expect("Init");

This allows customising the initialisation of the groups struct passed to init.

Finally, Error::Timeout has an inner enum describing the reason for a timeout. The change to Error is minimal:

use ethercrab::Error;

let result = /* snip */;

// EtherCrab 0.6
if let Error::Timeout = result {
    log::error!("Timeout!");
}

// EtherCrab 0.7
if let Error::Timeout(timeout) = result {
    log::error!("Timeout: {}", timeout);
}

New features

Not much to show here really, but there are still some niceties added:

Other fixes and small behavioural changes

What's next

Pretty much the same as EtherCrab 0.6...

As usual, if you have other features you'd like to see in EtherCrab, please open a feature request!

Thanks to everyone using and improving EtherCrab every day ❤️