-
Notifications
You must be signed in to change notification settings - Fork 2
EtherCAT HAL
ethercat_hal is a hardware abstraction layer for EtherCAT, built on
ethercrab (the QiTech fork, pinned by git revision). It gives
you three things:
- A master that runs in its own thread. It brings the bus up (Init → PreOp → Op), exchanges the process image every cycle, keeps distributed clocks (DC) in sync, and records every state transition for diagnostics.
- Lock-free cyclic data exchange between that thread and your application code.
-
Device drivers that turn raw process-image bits into typed values for specific terminals (Beckhoff,
WAGO and Panasonic). Machine code talks to them through hardware-agnostic
iotraits.
This reads the two inputs of an EL1002. The full version is in
examples/el1002_minimal.rs.
use bitvec::{order::Lsb0, slice::BitSlice};
use std::time::Duration;
use ethercat_hal::{
BECKHOFF_VENDOR_ID, EtherCATState, init_ethercat,
devices::{EthercatDevice, NewEthercatDevice, beckhoff_modules::el1002::{EL1002, EL1002_PRODUCT_ID}},
io::digital_input::DigitalInputDevice,
};
let control = init_ethercat("eth0", None); // spawns the master thread
let mut handle = control.app_handle;
control.channel.request_state_change(EtherCATState::PreOp)?;
while handle.get_state() != EtherCATState::PreOp { std::thread::sleep(Duration::from_millis(10)); }
control.channel.request_state_change(EtherCATState::Op)?;
while handle.get_state() != EtherCATState::Op { std::thread::sleep(Duration::from_millis(10)); }
let subdevices = handle.try_get_subdevices_vec_sync()?;
let mut el1002 = EL1002::new();
loop {
if let Some(inputs) = handle.get_inputs() {
for sd in &subdevices {
if sd.vendor == BECKHOFF_VENDOR_ID && sd.product_id == EL1002_PRODUCT_ID {
el1002.input(BitSlice::<u8, Lsb0>::from_slice(&inputs[sd.start_tx..sd.end_tx]))?;
}
}
}
println!("DI1={} DI2={}", el1002.get_input(0)?, el1002.get_input(1)?);
}To run it, pass the name of the network interface that the EtherCAT bus is connected to. Run this from the repository root:
cargo run --example el1002_minimal -- eth0The configured cargo runner (bin/run-linux) uses sudo setcap to grant the binary raw-socket and
real-time capabilities. Expect a sudo prompt.
| Document | Read it when you want to… |
|---|---|
| Architecture | understand the threads, the state machine, and how data moves between the master and your code |
| Application guide | write a program that brings up a bus, configures terminals, and runs a control loop |
| Writing device drivers | understand how a driver works (using the EL1002 and EL2002 as examples) or add support for a new terminal |
Derive macros (ethercat_hal_derive) |
look up exactly what PdoObject, TxPdo, RxPdo and EthercatDevice require and generate |
Only some terminals have their own page so far. For the rest, the driver source is the reference.
| Terminal | Page |
|---|---|
| EL6021 (serial RS422/RS485) | EL6021 |
| EL4732 (2 × analog output ±10 V, oversampling) | EL4732 |
| EL7031, EL7031-0030, EL7041-0052 (stepper motor) | EL70x1 steppers |
| WAGO 750-354 coupler + 750 slot modules (750-455, 750-531, 750-554 as examples) | WAGO 750 |
| Module | Contents |
|---|---|
lib.rs |
init_ethercat, EtherCATAppHandle, EtherCATThreadChannel, MasterConfiguration, MetaSubdevice, EtherCATState
|
controller.rs |
the master's state machine and cyclic loop (runs on the EthercatStateMachine thread) |
ethercat_helpers.rs |
the blocking request API on EtherCATThreadChannel (sdo_read, sdo_write, enable_dc_sync0, …) |
al_diagnostics.rs |
TransitionReport, TransitionLog, SubDeviceAlStatus
|
pdo/ |
the PDO traits (RxPdo, TxPdo, PdoObject) and reusable PDO object types |
devices/ |
one driver per terminal, plus the identity → driver lookup (device_from_subdevice_identity) |
io/ |
hardware-agnostic traits such as DigitalInputDevice and DigitalOutputDevice
|
coe.rs, shared_config/
|
CoE (SDO) configuration traits and shared config structs |
interface_discovery.rs |
lists network interfaces and tests which ones have an EtherCAT bus attached |
machine_ident_read.rs |
reads and writes QiTech machine identification stored in terminal EEPROM |
cd ethercat_hal && cargo testethercat_hal is not part of a Cargo workspace, so cargo test -p ethercat_hal from the repository root
does not work. The tests cover PDO encoding and decoding and the helper converters. None of them need
hardware.
EtherCAT HAL
EtherCAT Devices
XTREM
Other crates