跳到主要内容

Slave API

通过 master.slave(n) 获取从站句柄 (1-based 索引),或通过 master.slaves() 获取所有从站。

快速开始

索引访问

let slave = master.slave(1);           // 第1个从站 (1-based)
let count = master.slave_count(); // 从站总数 (u16)
let all = master.slaves(); // 所有从站 Vec<Slave>

标识访问

let name: String = slave.name();            // 设备名称
let drive_name: String = slave.drive_name(); // 驱动名称 (SDO 0x1008)
let vendor_id: u32 = slave.vendor_id(); // 厂商 ID
let product_id: u32 = slave.product_id(); // 产品 ID
let revision: u32 = slave.rev_id(); // 修订号
let serial: u32 = slave.serial_number(); // 序列号

地址访问

let addr: u16 = slave.config_addr();        // 物理配置地址
let alias: u16 = slave.alias_address(); // 别名地址

// 按地址查找
let target = master.slaves().iter()
.find(|s| s.config_addr() == 0x1001);

组访问

// 查询从站所在组
let group: u8 = slave.group();

// 查询组内从站数
let group_count = master.group_slave_count(1);
提示

组相关属性详见 从站分组

协议访问

协议方法说明
SDOslave.sdo_read_value::<T>() / sdo_write_value()类型化 SDO 读写
OD 树OdList::load(master_idx, slave_idx)对象字典遍历
CiA 402CiA402Instance::new(master_idx, slave_idx, pdo_map)独立构造伺服驱动器实例
SoEslave.soe()Servo over EtherCAT
FoEslave.foe()File over EtherCAT
EoEslave.eoe()Ethernet over EtherCAT
AoEslave.aoe()ADS over EtherCAT
VoEslave.voe()Vendor over EtherCAT
FSoEFsoeManager / FsoeMdp功能安全协议 (独立构造)
MDPmdp_discover()模块化设备发现 (模块级函数)
DCslave.dc()DC 同步配置

PDO 数据读写

io(&self) -> Result<(i32, *mut u8, i32, *mut u8)> 获取 IO 映射指针和大小, 返回 (输出字节数, 输出指针, 输入字节数, 输入指针)。除原始字节与结构体映射外, SDK 还支持按类型 直接读写 PDO, 无需定义结构体, 详见 PDO 输入输出

let slave = master.slave(1);
let (out_size, _out_ptr, in_size, _in_ptr) = slave.io()?;
println!("输出 {} 字节, 输入 {} 字节", out_size, in_size);

// 按类型读取输入 PDO (offset 为字节偏移量, 直接返回值)
let bits: u8 = slave.read_input_u8(0); // 数字输入
let status: u16 = slave.read_input_u16(2); // StatusWord
let position: i32 = slave.read_input_i32(4); // ActualPosition
let torque: i16 = slave.read_input_i16(8); // ActualTorque

// 按类型写入输出 PDO (offset 为字节偏移量, 无返回值)
slave.write_output_u8(0, 0xFF); // 数字输出
slave.write_output_u16(2, 0x000F); // ControlWord
slave.write_output_i32(4, 100000); // TargetPosition
slave.write_output_i16(8, 500); // TargetTorque

支持的类型: u8 / i8 (1 字节)、u16 / i16 (2 字节)、u32 / i32 / f32 (4 字节)。

SDO 读写示例:

// 类型化读取
let status: u16 = slave.sdo_read_value(0x6041, 0x00)?;
let position: i32 = slave.sdo_read_value(0x6064, 0x00)?;

// 类型化写入
slave.sdo_write_value(0x6040, 0x00, &0x0006u16)?;

// 原始字节读写 (第三个参数: complete_access)
let data = slave.sdo_read(0x1000, 0x00, false)?;
slave.sdo_write(0x6040, 0x00, false, &[0x06, 0x00])?;

EMCY 紧急消息

use ethercat::{emcy_get_count, emcy_get_history, emcy_clear_history};

let count = emcy_get_count(master.index(), 1);
let history = emcy_get_history(master.index(), 1);
for msg in &history {
println!("错误码: 0x{:04X}", msg.error_code);
}
emcy_clear_history(master.index(), 1);

拓扑查询

主站层提供两套拓扑接口, 按使用场景选择:

平铺节点列表 (topology() / topology_build()) — 适用于只需要节点列表 / 子节点 / 根节点的简单查询场景。

let topo = master.topology();              // Vec<TopologyNode>, 第一次构建后缓存
let topo2 = master.topology_build(); // 强制重建 (重新扫描后调用)

let children = master.topology_get_children(1); // 直接子节点 Vec<u16>
let roots = master.topology_get_roots(); // 根节点 Vec<u16>

高级 SlaveTopology 对象 (slave_topology()) — 返回封装好的 SlaveTopology 实例, 内部一次扫描后构建 parent/children 双向索引, 支持深度计算 / 路径查找 / 按地址查询等结构化 遍历。适合需要在拓扑树上做多次查询的工具型代码 (如 IDE 拓扑图、配置导出器)。

pub fn slave_topology(&self) -> SlaveTopology
let topo = master.slave_topology();

topo.nodes(); // &[TopologyNode] — 全部节点
topo.count(); // usize — 节点数
topo.root_slaves(); // &[u16] — 根从站列表
topo.children(parent_idx); // &[u16] — 子从站索引
topo.child_count(parent_idx);// usize — 子节点数
topo.get(slave_index); // Option<&TopologyNode>
topo.get_by_address("0x1001"); // Option<&TopologyNode>, 支持 hex / dec
topo.parent_of(slave_index); // Option<u16>
topo.depth(slave_index); // u32 — 到根节点距离
何时用哪个
  • 快速查询根 / 子节点topology_get_children / topology_get_roots
  • 构建拓扑可视化 / 多次结构化查询slave_topology(), 一次构建复用
  • 重新扫描后topology_build() 或重新调用 slave_topology()

启动参数 (add_startup_parameter / clear_startup_parameters):

// 添加启动参数
slave.add_startup_parameter(
0x1C12, 0x00, // 索引, 子索引
&[0x00], // 数据
TRANS_IP, // Init -> PreOp 转换时
TIMING_BEFORE, // 转换前执行
false, // 非 Complete Access
);

// 清除所有启动参数
slave.clear_startup_parameters();