RTT optimization: 8kHz support, io_uring backend option (tested slower), RT-promote tx_rx thread; 8kHz RTT min 0.75ms mean 1.04ms

This commit is contained in:
Tony Cao 2026-08-12 21:47:50 +08:00
parent d95973ab68
commit 4083df04fb
2 changed files with 20 additions and 5 deletions

View File

@ -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"

View File

@ -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<Config, String> {
@ -120,6 +122,7 @@ fn parse_args() -> Result<Config, String> {
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<Config, String> {
"--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<dyn std::error::Error>> {
);
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);
}
}
});