ethercrab icon indicating copy to clipboard operation
ethercrab copied to clipboard

Windows '\Device\NPF_{YOUR-ADAPTER-ID}'

Open runtimevic opened this issue 7 months ago • 3 comments

Hello, In Windows, how can I know?

$env:RUST_LOG="debug" ; cargo run --example ek1100 --release -- '\Device\NPF_{YOUR-ADAPTER-ID}'

$env:RUST_LOG="debug" ; cargo run --example ek1100 --release -- '\Device\NPF_{FF0ACEE6-E8CD-48D5-A399-619CD2340465}'

runtimevic avatar Sep 26 '25 21:09 runtimevic

I don't have a Windows PC to hand, but I believe it's something like

wmic nic get name, deviceid

Or

Get-NetAdapter | Select-Object Name, InterfaceDescription

Please let me know if either of these work (or which command you used) and I'll add an FAQ entry somewhere.

jamwaffles avatar Sep 26 '25 22:09 jamwaffles

hello @jamwaffles,

Cargo.toml

[package]
name = "Rust-EK1100"
version = "0.1.0"
edition = "2021"

[dependencies]
ethercrab = { version = "0.2.0", features = ["std"] }
log = { version = "0.4.27", features = ["std"] }
env_logger = "0.10"
smol = "1.3"
heapless = "0.8"
pnet_datalink = "0.34.0"

main.rs

//! Discover devices connected to the network.

use env_logger::Env;
use ethercrab::{
    Client,
    ClientConfig,
    PduStorage,
    Timeouts,
};
use std::sync::Arc;

/// Maximum number of SubDevices that can be stored. This must be a power of 2 greater than 1.
const MAX_SUBDEVICES: usize = 128;
/// Maximum PDU data payload size
const MAX_PDU_DATA: usize = 1100;
/// Maximum number of EtherCAT frames that can be in flight at any one time.
const MAX_FRAMES: usize = 16;
/// Maximum total PDI length.
const PDI_LEN: usize = 64;

static PDU_STORAGE: PduStorage<MAX_FRAMES, MAX_PDU_DATA> = PduStorage::new();

fn main() {
    env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();

    // List available network interfaces
    let interfaces = pnet_datalink::interfaces();
    
    if std::env::args().len() < 2 {
        println!("Please provide a network interface name as an argument.");
        println!("\nAvailable interfaces:");
        for iface in interfaces {
            println!("- {} ({})", iface.name, iface.description);
        }
        std::process::exit(1);
    }

    let interface = std::env::args()
        .nth(1)
        .expect("Provide network interface as first argument.");

    // Verify interface exists
    if !interfaces.iter().any(|iface| iface.name == interface) {
        println!("Error: Interface '{}' not found.", interface);
        println!("\nAvailable interfaces:");
        for iface in interfaces {
            println!("- {} ({})", iface.name, iface.description);
        }
        std::process::exit(1);
    }

    log::info!("Discovering EtherCAT devices on {}...", interface);

    let (tx, rx, pdu_loop) = PDU_STORAGE.try_split().expect("can only split once");

    let maindevice = Arc::new(Client::new(
        pdu_loop,
        Timeouts::default(),
        ClientConfig {
            dc_static_sync_iterations: 0,
            ..ClientConfig::default()
        },
    ));

    smol::block_on(async {
        #[cfg(target_os = "windows")]
        std::thread::spawn(move || {
            ethercrab::std::tx_rx_task(
                &interface,
                tx,
                rx,
            )
            .expect("TX/RX task")
        });

        #[cfg(not(target_os = "windows"))]
        smol::spawn(ethercrab::std::tx_rx_task(&interface, tx, rx).expect("spawn TX/RX task"))
            .detach();

        let mut group = maindevice
            .init_single_group::<MAX_SUBDEVICES, PDI_LEN>()
            .await
            .expect("Init");

        log::info!("Discovered {} SubDevices", group.len());

        for subdevice in group.iter(&maindevice) {
            log::info!(
                "--> SubDevice {:#06x} name {}, {}",
                subdevice.configured_address(),
                subdevice.name(),
                subdevice.identity()
            );
        }
    });

    log::info!("Done.");
}

cargo run -- "\Device\NPF_{81772805-D898-4CDF-B345-365BD7BBC028}"


    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.09s
     Running `target\debug\Rust-EK1100.exe \Device\NPF_{81772805-D898-4CDF-B345-365BD7BBC028}`
[2025-09-27T19:26:34Z INFO  Rust_EK1100] Discovering EtherCAT devices on \Device\NPF_{81772805-D898-4CDF-B345-365BD7BBC028}...

thread 'main' has overflowed its stack
error: process didn't exit successfully: `target\debug\Rust-EK1100.exe \Device\NPF_{81772805-D898-4CDF-B345-365BD7BBC028}` (exit code: 0xc00000fd, STATUS_STACK_OVERFLOW)

(exit code: 0xc00000fd, STATUS_STACK_OVERFLOW)


config.toml

[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "link-args=/STACK:8000000"]

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.07s
     Running `E:\_Rust-Proyectos\Rust-EtherCrab-EK1100\target\debug\Rust-EK1100.exe \Device\NPF_{81772805-D898-4CDF-B345-365BD7BBC028}`
[2025-09-27T19:35:28Z INFO  Rust_EK1100] Discovering EtherCAT devices on \Device\NPF_{81772805-D898-4CDF-B345-365BD7BBC028}...
[2025-09-27T19:35:28Z ERROR ethercrab::client] Write service timeout, command Bwr { address: 0, register: 288 }, timeout 30 ms

thread 'main' panicked at src\main.rs:83:14:
Init: Timeout
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `E:\_Rust-Proyectos\Rust-EtherCrab-EK1100\target\debug\Rust-EK1100.exe \Device\NPF_{81772805-D898-4CDF-B345-365BD7BBC028}` (exit code: 101)

get\debug\Rust-EK1100.exe \Device\NPF_{DEA6B43D-48A2-439B-BDAD-67240E099652}` (exit code: 1)
PS D:\_Rust-Proyectos\Rust-EtherCrab-EK1100> $env:RUST_LOG="debug,ethercrab=trace"; cargo run -- "`\Device\NPF_{DEA6B43D-48A2-439B-BDAD-67240E099652}"
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.07s
     Running `target\debug\Rust-EK1100.exe \Device\NPF_{DEA6B43D-48A2-439B-BDAD-67240E099652}`
[2025-09-27T21:03:18Z INFO  Rust_EK1100] Discovering EtherCAT devices on \Device\NPF_{DEA6B43D-48A2-439B-BDAD-67240E099652}...
[2025-09-27T21:03:18Z DEBUG Rust_EK1100] Starting TX/RX task...
[2025-09-27T21:03:18Z DEBUG Rust_EK1100] TX/RX task started successfully
[2025-09-27T21:03:19Z DEBUG Rust_EK1100] Initializing device group...
[2025-09-27T21:03:19Z DEBUG ethercrab::client] Beginning reset
[2025-09-27T21:03:19Z TRACE ethercrab::pdu_loop::storage] Try to allocate frame #0
[2025-09-27T21:03:24Z ERROR ethercrab::client] Write service timeout, command Bwr { address: 0, register: 288 }, timeout 5000 ms
[2025-09-27T21:03:24Z ERROR Rust_EK1100] Failed to initialize device group: Timeout
error: process didn't exit successfully: `target\debug\Rust-EK1100.exe \Device\NPF_{DEA6B43D-48A2-439B-BDAD-67240E099652}` (exit code: 1)

Now I have this problem, it doesn't detect the EK1100...

  • Can ethercrab run on Windows 11?
  • Do I need a special Ethernet card for it to work?
  • Realtek PCIe GbE Family Controller is my network is possible? I have tested it with TwinCAT 3 and the EK1100 works OK with an EL2008 digital output card...

runtimevic avatar Sep 27 '25 19:09 runtimevic

Thanks for sharing your debugging steps.

Can ethercrab run on Windows 11?

I believe so, or it at least definitely runs on Windows 10, as I spent some time developing EtherCrab on Windows 10.

Do I need a special Ethernet card for it to work?

No, a standard NIC should be fine :). Check that TwinCAT isn't running, however - that might be messing stuff up if it's still holding some kind of reference to the NIC you're trying to use with EtherCrab.

Have you looked at examples/windows.rs? It has a few Windows-specific notes and tweaks. I'd still recommend Linux (or macOS at a push) however; Windows has pretty poor performance.

jamwaffles avatar Sep 28 '25 20:09 jamwaffles