配置
通过 master.config() 获取 MasterConfig<'_>,统一管理所有通信配置。
属性
| 类别 | 方法 | 类型 | 读写 | 说明 |
|---|---|---|---|---|
| 周期配置 | loop_cycle() / set_loop_cycle() | u32 | 读写 | PDO 交换周期 (纳秒) |
| 网络传输 | frame_high_priority() / set_frame_high_priority() | bool | 读写 | 帧高优先级(默认关闭) |
| use_udp() / set_use_udp() | bool | 读写 | UDP 帧模式(仅网关/EAP 设备可用) | |
| is_udp_available() | bool | 只读 | UDP 是否可用 | |
| vlan_id() / set_vlan_id() | u16 | 读写 | VLAN ID (0-4095, 0=禁用) | |
| vlan_priority() / set_vlan_priority() | u8 | 读写 | VLAN 优先级 PCP (0-7) | |
| PDO 配置 | overlapping_groups() / set_overlapping_groups() | bool | 读写 | PDO 重叠模式(默认不启用,仅 TI ESC) |
| packed_mode() / set_packed_mode() | bool | 读写 | Packed PDO 映射模式 (false=字节对齐, true=bit紧密映射) | |
| 互斥锁 | mutex_protection() / set_mutex_protection() | bool | 读写 | 互斥锁保护(默认启用) |
| 自适应超时 | adaptive_timeout_enabled() / set_adaptive_timeout_enabled() | bool | 读写 | 自适应超时(默认启用) |
| 状态转换超时 | timeout_init_to_preop() / set_timeout_init_to_preop() | u32 | 读写 | INIT->PREOP 超时 (ms, 默认 3000) |
| timeout_preop_to_safeop() / set_timeout_preop_to_safeop() | u32 | 读写 | PREOP->SAFEOP 超时 (ms, 默认 10000) | |
| timeout_safeop_to_op() / set_timeout_safeop_to_op() | u32 | 读写 | SAFEOP->OP 超时 (ms, 默认 5000) | |
| 看门狗 | process_data_watchdog_ms() / set_process_data_watchdog_ms() | u32 | 读写 | 过程数据看门狗 (ms) |
| pdi_watchdog_ms() / set_pdi_watchdog_ms() | u32 | 读写 | PDI 看门狗 (ms) | |
| 扫描配置 | scan_revision_match() / set_scan_revision_match() | u8 | 读写 | 扫描修订号匹配模式 (0=精确, 1=兼容, 2=忽略) |
| 帧重复 | frame_repeat_count() / set_frame_repeat_count() | u8 | 读写 | 帧重复次数 (1-3, 默认 1=禁用) |
| DC 配置 | drift_compensation() / set_drift_compensation() | bool | 读写 | DC 漂移补偿 |
| 邮箱配置 | mailbox_timeout() / set_mailbox_timeout() | u32 | 读写 | 邮箱通信超时 (毫秒, 默认 5000) |
| mailbox_retries() / set_mailbox_retries() | u32 | 读写 | 邮箱通信重试次数 (默认 3) |
周期配置
loop_cycle() / set_loop_cycle()
pub fn loop_cycle(&self) -> u32
pub fn set_loop_cycle(&self, ns: u32)
PDO 交换周期时间,单位:纳秒 (ns)。
主站 RT 线程(WDK 内核定时器驱动)以此周期执行 PDO 帧的发送和接收。该值决定了主站与从站之间过程数据的刷新频率 -- 值越小,数据刷新越快,但对系统实时性要求也越高。WDK 驱动最低支持 31.25μs。
Windows 系统建议不低于 125,000ns (125us)。WDK 驱动完全支持 31.25us,更小的值在 Windows 上没有意义,应用层无法做到更高频的写入。Linux 系统根据内核配置可支持更短周期。
示例:
let config = master.config();
config.set_loop_cycle(1_000_000); // 1ms
config.set_loop_cycle(500_000); // 500us
config.set_loop_cycle(250_000); // 250us
config.set_loop_cycle(125_000); // 125us (Windows 推荐最小值)
DC 漂移补偿自动完成,无需额外配置。
DC 同步窗口监控由内部诊断线程自动管理(固定 100ms 间隔),网络中有 DC 从站时自动启用。
邮箱通信自动附带在 PDO 周期中,不占用额外帧。
邮箱响应延迟: 约 2-3 个 PDO 周期。如 loop_cycle=1ms,SDO 读取约需 2-3ms。
网络传输
frame_high_priority() / set_frame_high_priority()
pub fn frame_high_priority(&self) -> bool
pub fn set_frame_high_priority(&self, enabled: bool)
通过 OS 层提升 EtherCAT 帧的发送优先级,减少排队延迟。
默认值: false(默认关闭)
- Windows — 进程/线程优先级提升
- Linux — SO_PRIORITY=6 socket 选项(内核网络栈排队优先级,需要 root 权限)
use_udp() / set_use_udp()
pub fn use_udp(&self) -> bool
pub fn set_use_udp(&self, enabled: bool)
UDP 帧模式(ETG.1500 5.3.7)。启用后,EtherCAT 数据报封装在 UDP/IP 数据包中传输(UDP 端口 34980)。
标准 EtherCAT 从站的 ESC(EtherCAT Slave Controller)芯片在数据链路层工作,只能识别 EtherType=0x88A4 的原始以太网帧。UDP/IP 封装的帧对这些从站不可见。
仅适用于:
- 使用支持 UDP 协议的 EtherCAT 网关或桥接设备
- 与 EtherCAT Automation Protocol(EAP)设备通信
不适用于: 直连标准 EtherCAT 从站(EK1100、EL7041、伺服驱动等)
is_udp_available()
pub fn is_udp_available(&self) -> bool
系统初始化时是否成功创建了 UDP socket。只有此方法返回 true 时,才能通过 set_use_udp() 切换到 UDP 模式。
在某些受限环境中(如缺少网络权限、防火墙阻止等),UDP socket 可能创建失败,此时 is_udp_available() 返回 false,调用 set_use_udp(true) 将无效。
示例:
if master.config().is_udp_available() {
master.config().set_use_udp(true); // 切换到 UDP 模式
}
vlan_id() / set_vlan_id()
pub fn vlan_id(&self) -> u16
pub fn set_vlan_id(&self, id: u16)
VLAN ID(IEEE 802.1Q, ETG1000_4 表9, ETG.1500 可选功能)。范围 0-4095,0 表示禁用 VLAN 标签。
设置非零值后,所有 EtherCAT 帧将插入 4 字节的 802.1Q VLAN 标签,帧头从标准的 14 字节变为 18 字节。
VLAN 配置需要在进入 SafeOp 之前设置(Build 成功后、set_state(Op) 之前)。
VLAN 标签功能仅在安装了 WDK 内核驱动时生效。WDK 内核驱动直接发送原始帧,VLAN 标签完整保留在线缆上。
vlan_priority() / set_vlan_priority()
pub fn vlan_priority(&self) -> u8
pub fn set_vlan_priority(&self, pcp: u8)
VLAN 优先级(PCP -- Priority Code Point, IEEE 802.1Q, ETG.1500 可选功能)。范围 0-7,7 为最高优先级。编码在 VLAN 标签的 TCI 字段高 3 位中。
需要先设置 vlan_id() 为非零值,且使用 WDK 驱动模式,此属性才有意义。在支持 QoS 的交换机中,高 PCP 值的帧将优先转发。
VLAN 典型应用场景:
- IT/OT 融合网络 -- 通过 VLAN 隔离工业控制流量与办公网络流量
- TSN(时间敏感网络) -- IEEE 802.1Q 优先级标签实现 QoS 调度
- 多网段共存 -- 同一物理网络承载多个 EtherCAT 网段
示例:
// build() 成功后设置 VLAN(需要 WDK 驱动模式)
let config = master.config();
// 在进入 SafeOp 之前配置 VLAN
config.set_vlan_id(100);
config.set_vlan_priority(6); // 高优先级
PDO 配置
overlapping_groups() / set_overlapping_groups()
pub fn overlapping_groups(&self) -> bool
pub fn set_overlapping_groups(&self, enabled: bool)
PDO 重叠模式开关。启用后,每个从站的输出和输入共享同一段逻辑地址(取两者中较大的尺寸),LRW 命令发送时写入输出,返回时 ESC 用输入数据替换同一位置,从而减少帧大小。
默认值: false(默认不启用)
只能在 INIT 或 PRE_OP 状态下设置,因为内存布局在进入 SAFE_OP 时已确定。
重叠仅发生在帧的逻辑地址层面。slave.read_input_*() / slave.write_output_*() 与 SlavePdo 的输入 / 输出始终指向独立的内存区域,slave.ibytes() / slave.obytes() 不变,所有 API 行为一致。
使用 TI (Texas Instruments) EtherCAT Slave Controller 的从站必须启用重叠模式,否则 LRW 命令无法正确工作。标准 Beckhoff/第三方从站请勿启用,部分从站不支持 FMMU 逻辑地址重叠会拒绝 SAFE_OP 转换。
packed_mode() / set_packed_mode()
pub fn packed_mode(&self) -> bool
pub fn set_packed_mode(&self, enabled: bool)
Packed PDO 映射模式开关。启用后,PDO 变量按 bit 紧密排列,不强制字节对齐。
默认值: false(默认禁用,字节对齐模式)
只能在 INIT 或 PRE_OP 状态下设置,因为内存布局在进入 SAFE_OP 时已确定。
适用于 bit-level IO 模块(如 Beckhoff EL1008/EL2008 等数字 IO 终端),这些模块的 PDO 数据为单个 bit,启用 packed_mode 可以将多个 bit IO 紧密排列在连续内存中,节省 IOmap 空间。
示例:
config.set_packed_mode(true); // 启用 bit 紧密排列
PDO 配置与从站分组配合使用。每组独立的分频器和丢帧跟踪意味着高频组和低频组的丢帧互不影响。
扫描配置
scan_revision_match() / set_scan_revision_match()
pub fn scan_revision_match(&self) -> u8
pub fn set_scan_revision_match(&self, mode: u8)
扫描从站时的版本匹配策略。控制 build() 过程中扫描到的从站与 DENI 配置中从站的版本号匹配严格程度。
默认值: 2(忽略修订号)
相关枚举:
#[repr(u8)]
pub enum ScanRevisionMatchMode {
Exact = 0, // 精确匹配 VendorID + ProductID + RevisionID
CompatibleHigher = 1, // 兼容匹配: 扫描到的 RevisionID >= 配置的 RevisionID
IgnoreRevision = 2, // 忽略 RevisionID, 仅匹配 VendorID + ProductID(默认)
}
示例:
config.set_scan_revision_match(1); // 兼容匹配
帧重复
frame_repeat_count() / set_frame_repeat_count()
pub fn frame_repeat_count(&self) -> u8
pub fn set_frame_repeat_count(&self, count: u8)
帧重复机制(ETG.1500 5.4.3),全局设置每周期发送相同 PDO 帧的次数,自动对符合条件的组生效。
默认值: 1(禁用),范围 1-3
此方法为主站级全局设置,运行时自动按组过滤 -- 仅对组内所有从站均在 ESI 中声明 FrameRepeatSupport=1 的组执行帧重复。组资格在 IO 映射阶段自动计算:
- 组内所有从站都支持 -> 该组启用帧重复
- 组内有任何一个不支持 -> 该组跳过帧重复
ETG.1500 将帧重复定义为主站级能力,重复次数全局统一。由于 EtherCAT PDO 帧以 LRW 广播方式发送,同一帧内无法对个别从站区分处理,因此按组"全有或全无"是唯一合规做法。不需要为每组单独设置不同的重复次数。
此参数及每个从站的 FrameRepeatSupport 标志均已包含在 DENI 配置文件中。导出 DENI 后加载到另一台主站时,无需 ESI 文件即可正确计算每组的帧重复资格。
示例:
// 全局设置: 对所有符合条件的组,每周期发送 2 次相同 PDO 帧
config.set_frame_repeat_count(2);
互斥锁保护
mutex_protection() / set_mutex_protection()
pub fn mutex_protection(&self) -> bool
pub fn set_mutex_protection(&self, enabled: bool)
互斥锁保护开关。控制 PDO 读写时是否自动加锁确保线程安全。
- 启用(默认) -- 框架自动加锁保证线程安全
- 禁用 -- 关闭自动互斥锁,由用户自行管理线程安全,减少锁竞争开销
默认值: true
禁用互斥锁保护后,用户需要自行确保 PDO 数据的线程安全。适用于对延迟有极致要求且能自行管理并发的场景。
自适应超时
adaptive_timeout_enabled() / set_adaptive_timeout_enabled()
pub fn adaptive_timeout_enabled(&self) -> bool
pub fn set_adaptive_timeout_enabled(&self, enabled: bool)
自适应超时功能。启用后自动采样 RTT,动态计算最优 PDO 超时值。
默认值: true
状态转换超时
timeout_init_to_preop() / set_timeout_init_to_preop()
pub fn timeout_init_to_preop(&self) -> u32
pub fn set_timeout_init_to_preop(&self, ms: u32)
INIT->PREOP 超时 (ms)。0 = 使用默认 3000ms。
timeout_preop_to_safeop() / set_timeout_preop_to_safeop()
pub fn timeout_preop_to_safeop(&self) -> u32
pub fn set_timeout_preop_to_safeop(&self, ms: u32)
PREOP->SAFEOP 超时 (ms)。0 = 使用默认 10000ms。此阶段包含 SM/FMMU 配置和 PDO 映射,通常耗时最长。
timeout_safeop_to_op() / set_timeout_safeop_to_op()
pub fn timeout_safeop_to_op(&self) -> u32
pub fn set_timeout_safeop_to_op(&self, ms: u32)
SAFEOP->OP 超时 (ms)。0 = 使用默认 5000ms。
- 从站数量多 — 大型网络 (>50 从站) 可能需要增大 PreOp->SafeOp 超时
- 特殊从站 — 某些伺服驱动器或安全设备初始化较慢
- 调试阶段 — 增大超时以便观察转换过程
看门狗
pdi_watchdog_ms() / set_pdi_watchdog_ms()
pub fn pdi_watchdog_ms(&self) -> u32
pub fn set_pdi_watchdog_ms(&self, ms: u32)
PDI 看门狗超时 (ms)。监控从站本地应用程序对 ESC 的访问。
默认值: 0 (使用从站默认值)
process_data_watchdog_ms() / set_process_data_watchdog_ms()
pub fn process_data_watchdog_ms(&self) -> u32
pub fn set_process_data_watchdog_ms(&self, ms: u32)
过程数据看门狗超时 (ms)。监控主站到从站的 PDO 通信。
默认值: 0 (使用从站默认值,通常为 100ms)
过程数据看门狗超时应大于 PDO 周期的 10-100 倍。例如 loop_cycle=1ms 时,看门狗设为 100-200ms。
DC 配置
drift_compensation() / set_drift_compensation()
pub fn drift_compensation(&self) -> bool
pub fn set_drift_compensation(&self, enabled: bool)
DC 漂移补偿开关。启用后主站周期性检测 DC 系统时间偏差并写入补偿值 (0x0920)。
默认值: false
也可通过 master.enable_drift_compensation() 方法启用,该方法额外支持配置阈值和增益参数。
邮箱配置
mailbox_timeout() / set_mailbox_timeout()
pub fn mailbox_timeout(&self) -> u32
pub fn set_mailbox_timeout(&self, ms: u32)
邮箱通信超时 (毫秒)。
默认值: 5000
mailbox_retries() / set_mailbox_retries()
pub fn mailbox_retries(&self) -> u32
pub fn set_mailbox_retries(&self, count: u32)
邮箱通信重试次数。
默认值: 3
IOmap 锁定
lock_iomap() / unlock_iomap() / iomap_guard()
pub fn lock_iomap(&self)
pub fn unlock_iomap(&self)
pub fn iomap_guard(&self) -> IomapGuard<'_>
手动锁定/解锁 IOmap,用于多轴批量原子写入。当 set_mutex_protection(false) 时,需要手动调用此方法保证 PDO 数据的原子性。
Rust SDK 额外提供 RAII 守卫 IomapGuard,作用域结束时自动解锁。
三种线程安全模式对比:
- 自动互斥锁 —
set_mutex_protection(true)(默认)— ~200ns — 通用场景,无需关心线程安全 - 手动 IOmap 锁 —
set_mutex_protection(false)+lock_iomap/unlock_iomap— ~50ns — 多轴插补,需要批量原子写入 - 无锁 —
set_mutex_protection(false),不调用 lock — 0 — 单线程写入,保证无竞争
多轴联动插补时,多个从站的目标位置必须在同一 PDO 周期内同时生效。使用手动 IOmap 锁可以保证一批写入操作在一次 PDO 帧中原子提交。
iomap_guard() 返回 RAII 守卫,作用域结束自动解锁,避免忘记 unlock 导致死锁。
示例(多轴插补批量写入):
// 关闭自动互斥锁,改用手动 IOmap 锁
master.config().set_mutex_protection(false);
// 使用 RAII 守卫进行批量写入
{
let _guard = master.config().iomap_guard();
// 所有写入在守卫生命周期内完成,保证原子性
master.write_slave_output(1, &target_pos1.to_le_bytes());
master.write_slave_output(2, &target_pos2.to_le_bytes());
master.write_slave_output(3, &target_pos3.to_le_bytes());
} // _guard 离开作用域,自动解锁
完整示例
let config = master.config();
// 周期配置
config.set_loop_cycle(1_000_000); // 1ms
// 网络传输
config.set_frame_high_priority(true);
// 状态转换超时
config.set_timeout_preop_to_safeop(15000);
// 看门狗
config.set_pdi_watchdog_ms(100);
config.set_process_data_watchdog_ms(200);
// 帧重复
config.set_frame_repeat_count(2);
// 邮箱配置
config.set_mailbox_timeout(5000); // 5秒
config.set_mailbox_retries(3);
println!("{}", config); // Display 格式化
超时配置最佳实践
EtherCAT 通信涉及的多种超时字段彼此独立, 对网络异常的检测灵敏度和恢复时延有直接影响. 下表汇总常用字段、典型默认值与推荐范围, 实际部署时按照网络长度 / 干扰水平 / 实时性优先级三维平衡选取.
关键字段速查
loop_cycle(ns) — 默认 1,000,000 (1ms),推荐 125,000 ~ 4,000,000 — PDO 周期, 决定刷新率与 CPU 负载timeout_init_to_preop(ms) — 默认 3000,推荐 3000 ~ 10000 — INIT->PREOP 等待时间 (慢从站 / EEPROM 加载)timeout_preop_to_safeop(ms) — 默认 10000,推荐 10000 ~ 30000 — PREOP->SAFEOP 等待时间 (含 SM/FMMU/PDO 映射, 大网络可加大)timeout_safeop_to_op(ms) — 默认 5000,推荐 5000 ~ 15000 — SAFEOP->OP 等待时间process_data_watchdog_ms(ms) — 默认 0 (从站默认 ≈100),推荐 loop_cycle × 10 ~ 100 — 从站丢失主站连接后回退 SafeOp 的时间pdi_watchdog_ms(ms) — 默认 0 (从站默认),推荐 0 ~ 200 — 从站本地固件停止访问 ESC 的检测窗口mailbox_timeout(ms) — 默认 5000,推荐 1000 ~ 10000 — SDO / FoE / 紧急消息单次邮箱等待mailbox_retries(次) — 默认 3,推荐 1 ~ 10 — 邮箱失败重试次数
何时调大 / 调小
调大 适用场景:
- 长电缆 / 跨机柜 / 跨车间 -- 物理传输延迟大, 偶发 RTT 抖动需缓冲
- 高 EMI / 焊接 / 大功率变频器附近 -- 噪声造成偶发丢帧, 重试空间需放宽
- 跨 VLAN / TSN 复合网络 -- 经过交换机会引入排队抖动
- 大网络 (>50 从站) --
timeout_preop_to_safeop必须放大, 否则 SafeOp 转换失败 - 慢从站 (FoE 大文件下载 / EEPROM 写入) -- 邮箱 / Init->PreOp 都要拉长
调小 适用场景:
- 快速故障检测优先 -- 工业紧急停车场景, 看门狗调到 5×loop_cycle, 50ms 内检测到丢帧
- 桌面短电缆 / 实验室 -- RTT 极低, 看门狗可下探到 20~50ms
- RT 严苛 (≤ 250µs 周期) -- 整体时序紧凑, 任何超时都要短
默认 / 实验室 / 工业 / 高 EMI 四档示例
let config = master.config();
// (1) SDK 默认 — 适合标准短电缆 + 桌面 ~ 普通车间
config.set_loop_cycle(1_000_000); // 1ms
config.set_timeout_preop_to_safeop(10000);
config.set_process_data_watchdog_ms(0); // 从站默认 (~100ms)
config.set_mailbox_timeout(3000);
// (2) 实验室高速 — 短线 + 严苛 RT
config.set_loop_cycle(250_000); // 250us
config.set_timeout_preop_to_safeop(5000);
config.set_process_data_watchdog_ms(20); // 极快检测
config.set_mailbox_timeout(1000);
// (3) 工业典型 — 长电缆 + 大网络
config.set_loop_cycle(1_000_000);
config.set_timeout_preop_to_safeop(20000); // 大网络放宽
config.set_process_data_watchdog_ms(200);
config.set_mailbox_timeout(5000);
// (4) 高 EMI / 焊接现场 — 容忍偶发丢帧
config.set_loop_cycle(2_000_000); // 2ms
config.set_timeout_preop_to_safeop(30000);
config.set_process_data_watchdog_ms(500);
config.set_mailbox_timeout(10000);
config.set_adaptive_timeout_enabled(true); // 自适应吸收抖动
- 超时太大 -- 真实故障也要等到超时才上报, 应用层告警 / 安全停机延迟变长
- 超时太小 -- 偶发抖动被误判成故障, 频繁触发
on_pdo_frame_loss/on_state_change噪声告警 - 看门狗 < loop_cycle × 数倍 -- 正常运行也会触发, 从站反复回退 SafeOp
- 调整后建议跑 24h 通讯压力测试再上线
启用 set_adaptive_timeout_enabled(true) (默认开) 后, SDK 自动按真实 RTT 计算 PDO 单帧超时,
无需手动收紧 loop_cycle. 上面的 watchdog / state transition 字段仍需按场景配置.