diff --git a/Cargo.toml b/Cargo.toml index e62c2f2..471d9c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" description = "J1900 <-> TwinCAT 1 kHz communication verification over an EL6695 EtherCAT bridge" [dependencies] -ethercrab = { version = "0.7", default-features = false, features = ["std"] } +ethercrab = { version = "0.7", default-features = false, features = ["std", "io-uring"] } futures-lite = "2" libc = "0.2" crc32fast = "1.4" diff --git a/src/main.rs b/src/main.rs index f2edc6a..4d8a5b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,7 @@ use std::time::{Duration, Instant}; use el6695_rt::{bridge, regs, rt, stats}; use ethercrab::{ - std::{ethercat_now, tx_rx_task}, + std::{ethercat_now, tx_rx_task, tx_rx_task_io_uring}, MainDevice, MainDeviceConfig, PduStorage, Timeouts, }; use stats::OnlineStats; @@ -101,6 +101,8 @@ struct Config { /// Enable DC SYNC0 on the EL6695 secondary (cycle = --cycle-us) and print /// per-second DC phase/drift telemetry in the report line. dc: bool, + /// Use the io_uring-based blocking TX/RX loop instead of AF_PACKET poll. + iouring: bool, } fn parse_args() -> Result { @@ -120,6 +122,7 @@ fn parse_args() -> Result { el1252_every: 1, spin: false, dc: false, + iouring: false, }; let mut args = std::env::args().skip(1).peekable(); if let Some(a) = args.peek() { @@ -151,6 +154,7 @@ fn parse_args() -> Result { "--quiet" => cfg.quiet = true, "--spin" => cfg.spin = true, "--dc" => cfg.dc = true, + "--iouring" => cfg.iouring = true, "--el2202" => cfg.el2202 = true, "--el2202-dual" => { cfg.el2202 = true; @@ -236,10 +240,21 @@ async fn run(cfg: &Config) -> Result<(), Box> { ); let iface = cfg.iface.clone(); + let use_iouring = cfg.iouring; let _txrx = std::thread::spawn(move || { - let task = tx_rx_task(&iface, tx, rx).expect("create tx_rx task"); - if let Err(e) = futures_lite::future::block_on(task) { - eprintln!("tx_rx task ended with error: {:?}", e); + if let Err(e) = rt::promote_current_thread(1, 79, false) { + eprintln!("tx_rx RT promotion failed (continuing): {}", e); + } + if use_iouring { + match tx_rx_task_io_uring(&iface, tx, rx) { + Ok(_) => {} + Err(e) => eprintln!("io_uring tx_rx task ended with error: {:?}", e), + } + } else { + let task = tx_rx_task(&iface, tx, rx).expect("create tx_rx task"); + if let Err(e) = futures_lite::future::block_on(task) { + eprintln!("tx_rx task ended with error: {:?}", e); + } } });