冗余 (Redundancy)
EtherCAT 冗余通过双网卡 + 环形拓扑实现链路级容错: 主网口走 primary 帧, 副网口走 secondary 帧, 任一段断线时 SDK 自动从两侧 WKC 合并完成的从站状态, 整个网络仍正常运行.
通过 master 直接调用启用 / 强制故障转移, 通过 master.Diagnostics() 查看冗余诊断.
- 冗余诊断 /
RingMode/BreakPoint详见 主站诊断 - 冗余状态 - 冗余链路状态变化事件:
addRedundancyModeChangedListener
启用与状态
| 方法 | 返回类型 | 说明 |
|---|---|---|
| enableRedundancy(boolean) | boolean | 启用 / 禁用冗余 (需在 Start() 之前调用) |
| forceRedundancyFailover() | boolean | 强制故障转移(主站);false = 未切换(双向 merge 常不手动切) |
| forceFailover() | boolean | 同上,RedundancyManager 短名(对齐 C# ForceFailover) |
| checkRedundancyHealth() | boolean | 检查冗余健康状态 |
| RingMode() | int | 环拓扑冗余运行模式原始值 (0=Inactive, 1=Dual, 2=Degraded),可用 EtherCATTypes.RingMode.fromValue(...) 转为枚举 |
| SecondaryLinkStatus() | boolean | 副网口链路是否正常 |
| setRedProcessdata(int mode) | void | 设置冗余处理模式 |
| RedProcessdata() | int | 获取当前冗余处理模式 |
enableRedundancy(boolean)
public boolean enableRedundancy(boolean enable)
启用 / 禁用冗余. 必须在 Start() 之前调用, 且构造主站时已经通过
SetNetwork(primary, secondary) 指定副网卡.
forceRedundancyFailover() / forceFailover()
public boolean forceRedundancyFailover() // EtherCATMaster
public boolean forceFailover() // RedundancyManager
Java 公开短名为 forceFailover(RedundancyManager);主站上的 forceRedundancyFailover() 是同一 native 调用(ForceRedundancyFailover)。请求把发送路径切到副网口,供调试或计划性维护。
- 返回
true:native 执行了切换。 - 返回
false:未切换。常见原因是双向 merge 不手动切(两侧帧同时在跑,没有可切的主/备路)。
不得把 false 当成成功。
checkRedundancyHealth()
public boolean checkRedundancyHealth()
检查冗余健康状态.
RingMode()
public int RingMode()
获取环拓扑冗余运行模式原始值。返回 int(0 / 1 / 2),可用 EtherCATTypes.RingMode 枚举转换为强类型:
int raw = master.RingMode();
EtherCATTypes.RingMode mode = EtherCATTypes.RingMode.fromValue(raw); // INACTIVE / DUAL / DEGRADED
EtherCATTypes.RingMode 枚举:
public enum RingMode {
INACTIVE(0), // 未激活: 冗余监控未初始化
DUAL(1), // 双向冗余: 两端发送 LRW
DEGRADED(2); // 降级模式: 仅 primary 工作
}
SecondaryLinkStatus()
public boolean SecondaryLinkStatus()
副网口链路是否正常.
setRedProcessdata(int mode) / RedProcessdata()
public void setRedProcessdata(int mode)
public int RedProcessdata()
设置 / 获取冗余处理模式.
冗余 WKC 读取 (合并 WKC)
环形冗余下, 主帧 (primary) 从 P0 入网走 ring + branch, 副帧 (secondary) 从 P1 入网仅走 ring。某段断开时一侧帧只能看到断点之前的从站, 另一侧从反方向补齐 —— SDK 把两侧 WKC 合并, 得到本周期真正完成 PDO 交换的从站数。
铁律: 合并 WKC == 期望 WKC, 即网络完好; 此时单口 WKC 可以 < 期望, 不是故障。
Java SDK 暴露的是合并后的 WKC —— master.WKC() 已是主+副合并的权威实测值, 直接用它对比 master.ExpectedWKC() 即可判整体健康, 无需 (也无单独的高级方法) 去读主/副单口 WKC。
| 类别 | 方法 | 返回类型 | 读写 | 说明 |
|---|---|---|---|---|
| 合并 WKC (权威) | WKC() | short | 只读 | 主+副合并后本周期真正完成交换的从站数 |
| 期望 WKC | ExpectedWKC() | short | 只读 | 拓扑固定真值, 永不下调迁就劣化总线 |
| 冗余激活 | Diagnostics().isRedundancyActive() | boolean | 只读 | 双端口均有流量 (即存在被补偿的断点) |
判健康的正确写法 — 以合并 WKC 为准:
// ✅ 正确: 合并 WKC == 期望 WKC, 网络完好 (即使有断点被冗余补偿)
boolean linkHealthy = master.WKC() == master.ExpectedWKC();
if (linkHealthy && master.Diagnostics().isRedundancyActive()) {
System.out.println("有断点, 但冗余已补齐, 网络仍完整 (合并 WKC=" + master.WKC() + ")");
} else if (!linkHealthy) {
System.out.printf("真有从站掉了: 合并 WKC=%d < 期望=%d%n",
master.WKC(), master.ExpectedWKC());
}
完整示例
启用冗余 + 健康监控
try (EtherCATMaster master = EtherCATMaster.create()) {
master.SetNetwork("\\Device\\NPF_{primary-guid}", "\\Device\\NPF_{secondary-guid}");
// 启用冗余 (Start 前调用)
master.enableRedundancy(true);
// 订阅冗余模式变化
master.Events().addRedundancyModeChangedListener((mi, oldMode, newMode) -> {
System.out.printf("冗余模式: %s -> %s%n", oldMode, newMode);
});
master.setState(EcState.OP);
master.Start();
// 周期性健康检查
while (true) {
boolean healthy = master.checkRedundancyHealth();
int mode = master.RingMode();
boolean secOk = master.SecondaryLinkStatus();
System.out.printf("冗余: healthy=%b ring_mode=%d secondary_link=%b%n",
healthy, mode, secOk);
Thread.sleep(1000);
}
}
故障转移演练
boolean switched = master.forceRedundancyFailover();
if (!switched) {
// false = 未切换。常见原因: 双向 merge 不手动切
return;
}
Thread.sleep(500);
- ETG.1500 §5.7 Cable Redundancy
- 其他语言 SDK 对齐: C#
EnableRedundancy/ Pythonenable_redundancy/ C++EnableRedundancy/ Rustenable_redundancy