PDO 输入输出
对齐 C#:GetIO / Mapping 已退场,请用 copy_slave_input_pdo / write_slave_output_pdo generation 整帧 API。
邮箱通信自动附带在 PDO 周期中,不占用额外帧。邮箱响应延迟约 2-3 个 PDO 周期。
Rust 主路径是 generation 整帧复制:读走 copy_slave_input_pdo,写走 write_slave_output_pdo。调用方拿到 Vec<u8> owned 快照。
内核 SHM 零拷贝只存在于驱动内部,不向应用层暴露指针。不要再把 slave.io()、get_input_data_pointer、input_slice / output_slice、bind_pdo_struct 当成 IOmap overlay——这些入口已退场(返回 Err / null / 空切片 / None)。
主路径:generation 整帧
copy_slave_input_pdo() / copy_slave_output_pdo() / write_slave_output_pdo()
pub fn copy_slave_input_pdo(master_index: u16, slave_index: u16) -> Result<Vec<u8>>
pub fn copy_slave_output_pdo(master_index: u16, slave_index: u16) -> Result<Vec<u8>>
pub fn write_slave_output_pdo(master_index: u16, slave_index: u16, data: &[u8]) -> Result<usize>
与 C# CopyInputPdo / CopyOutputPdo / WriteOutputPdo 同一合同。write_slave_output_pdo 要求 data.len() 等于当前完整 RxPDO,绝不截断;禁止当局部 RMW 用。
SlavePdo 封装:
use darra_ethercat::SlavePdo;
let pdo = SlavePdo::new(master.index(), 1);
let input = pdo.try_inputs()?; // CopySlaveInputPdo
let mut output = pdo.try_outputs()?; // CopySlaveOutputPdo
if output.len() >= 6 {
output[0..2].copy_from_slice(&0x000Fu16.to_le_bytes());
output[2..6].copy_from_slice(&10_000i32.to_le_bytes());
pdo.try_write_outputs(&output)?; // WriteSlaveOutputPdo
}
PdoIoStatus
Failed=0, Ok=1, BufferTooSmall=2, SizeMismatch=3, Conflict=4, Stale=5, Busy=6。Busy 表示这一代 IOmap 被实时线程瞬占,可有界重试同一完整帧。不要把失败粉饰成成功。
同一路径上的便捷包装
下列入口不是第二套 PDO API,内部仍走整帧 copy / 版本化 patch。
read_input_data_direct/try_read_input_data_direct:从完整输入快照拷到用户缓冲write_output_data_direct/patch_slave_output_pdo:版本化 Begin→patch→Commitbatch_read/batch_write:一次快照或一次版本化事务SlavePdo::read_input_u16等:从完整帧切片;失败读折叠为 0PdoMonitor:对 owned 输入快照做变化检测
已退场(不要再用)
| 旧写法 | 现状 |
|---|---|
slave.io() | GetIO 已退场,返回 Err |
get_input_data_pointer / get_output_data_pointer | 固定 null |
input_data_view / output_data_view | deprecated,固定空 |
input_slice / output_slice / as_slice | deprecated,空切片 |
PdoDataItem / PdoArrayInstance | deprecated,访问 panic |
bind_pdo_struct / inputs_slice_mapping | deprecated,None / 空切片 |
需要结构体视图时:先 copy_slave_input_pdo,再从 &[u8] 按 packed 布局 from_le_bytes。不要假设能拿到跨周期仍有效的 IOmap 指针。
PDO 统计: 走 performance_stats / GetPDOStats,或 master.diagnostics_info()。
PDO 监控:
use darra_ethercat::PdoMonitor;
let mut monitor = PdoMonitor::new(master.index());
monitor.watch(1, "statusword", 0, 2);
for change in monitor.check() {
println!("从站 {} '{}' 变化", change.slave_index, change.watch_name);
}