跳到主要内容

错误处理

EtherCAT 通信中的错误处理策略和常见故障排查。

错误类型​

类型来源处理方式
AL Status Code从站状态转换失败通过 slave.ErrorCode() 读取,使用 EtherCATTypes.classifyALError() 分类
SDO ErrorCoE 读写失败SDO 方法返回 null 或 false
PDO 丢帧通信异常通过 PDOFrameLoss 事件 监控
Emergency从站硬件/固件错误通过 Emergency 事件 接收
状态降级从站异常回退通过 StateChanged 事件 监控
RuntimeException工厂方法失败EtherCATMaster.create() 初始化失败时抛出

状态转换错误​

检测方式​

boolean ok = master.setState(EcState.OP);
if (!ok) {
System.out.println("状态转换失败");
for (Slave slave : master.Slaves()) {
EtherCATTypes.EcALState errorCode = slave.ErrorCode();
if (errorCode != EtherCATTypes.EcALState.NO_ERROR) {
System.out.printf(" 从站 %d: AL 错误 %s (0x%04X)%n",
slave.SlaveNum, errorCode, errorCode.value);
}
}
}

错误分类​

使用 EtherCATTypes.classifyALError() 快速判断处理策略(参数为 AL 状态码 int):

EtherCATTypes.EcALState errorCode = slave.ErrorCode();
if (errorCode != EtherCATTypes.EcALState.NO_ERROR) {
EtherCATTypes.ALErrorCategory category =
EtherCATTypes.classifyALError(errorCode.value);
switch (category) {
case TRANSIENT:
// 瞬态错误(setState 内部已自动重试 3 次仍失败),通常需人工排查链路/电源
System.out.println("瞬态错误,已经过 SDK 内部重试仍未成功");
break;
case CONFIGURATION:
// 检查 PDO 映射、SM 配置
System.out.println("配置错误,请检查 PDO/SM 配置");
break;
case HARDWARE:
// 检查从站设备、线缆、电源
System.out.println("硬件错误,请检查从站设备");
break;
default:
break;
}
}
详细分类

完整的 AL 错误分类和常见错误码请参考 主站诊断 - AL 错误分类。

常见 AL Status Code​

  • 0x001E — 无效输入映射,检查 PDO 映射配置是否与从站支持的映射一致
  • 0x001D — 无效输出映射,检查 PDO 输出映射配置
  • 0x0017 — 无效 SM 配置,检查 SyncManager 配置(大小、方向)
  • 0x001B — SM 看门狗超时,PDO 周期过慢或通信中断
  • 0x002D — 同步错误,DC 同步配置问题,检查 SYNC0 周期
  • 0x0032 — DC 同步超时,DC 启动时间配置问题
  • 0x0003 — 无效设备设置,耦合器无物理模块,或模块配置不匹配

错误码 5023:数据闸关闭(授权未通过)​

原生层把 Windows ERROR_INVALID_STATE(5023)复用为数据闸关闭判据:授权未通过(未授权 / 授权过期 / 在线裁决 DENY / 完整性校验失败)时数据闸保持关闭,数据面调用直接被拒。

调用失败表现
setNetwork(...)返回值不 > 0(原生失败哨兵 0xFFFF)
setState() 进 SafeOp / OP返回 false

5023 与网卡无关。 见到 5023 不要去换网线、重装驱动或重新绑定网卡 —— 先查授权状态。

判读顺序:

  1. setNetwork() / setState() 失败后先读 master.getLastError(),不要凭返回值就归因网卡。
  2. 5023 = 数据闸 / 授权问题;1168 = ERROR_NOT_FOUND(NDIS 协议未绑定网卡);21 = ERROR_NOT_READY(驱动通道未就绪,瞬态可重试)。
  3. 其它值按 Windows 系统错误码解释。
int slaveCount = master.setNetwork("\\Device\\NPF_{...}");
if (slaveCount <= 0) {
int err = master.getLastError();
if (err == 5023) {
log.error("授权未通过(数据闸关闭),不是网卡问题");
} else if (err == 1168 || err == 21) {
log.error("网卡绑定 / 驱动通道问题(错误 {})", err);
}
}

事件驱动的异常处理​

推荐通过事件监控异常,而非轮询:

MasterEvents events = master.Events();

// 状态降级检测
events.addStateChangedListener((oldState, newState) -> {
System.out.println("状态变化: " + oldState + " -> " + newState);
});

// 从站离线
events.addSlaveOfflineListener((si) ->
System.out.println("从站 " + si + " 离线"));

// PDO 丢帧
events.addPDOFrameLossListener((mi, g, c, t) -> {
if (c > 10)
System.out.printf("组 %d 严重丢帧: 连续 %d 帧%n", g, c);
});

// 紧急消息
events.addEmergencyEventListener((mi, si, ec, er, b, w1, w2) ->
System.out.printf("从站 %d 紧急消息: 0x%04X%n", si, ec));
自动日志

所有事件(PDO 周期回调除外)触发时系统均自动记录日志,无论是否订阅。详见 事件。

常见故障排查​

create() 抛出异常​

  • 管理员权限不足 — 以管理员身份运行 JVM
  • JNA / 原生库加载失败 — 原生库 win32-x86-64/Darra.Core.dll 已内嵌在主 jar 内,由 JNA 从 classpath 抽出加载,无需再单独放置 DLL;排查时确认主 jar 完整未截断、JNA 为 5.14.0、未被 ProGuard 二次处理破坏
  • DLL 加载失败 — 检查 VC++ 运行时是否安装(x64)

从站无法进入 OP​

  • PDO 映射不匹配 — 检查 slave.ErrorCode(),常见 0x001E/0x001D
  • ESI 版本不匹配 — 使用与固件版本对应的 ESI 文件
  • DC 同步失败 — 检查 DC 配置,确认 SYNC0 周期合理
  • SM 配置错误 — 检查 SyncManager 大小和方向
  • 缺少启动参数 — 检查 Startup SDO 配置

通信不稳定​

  • 丢帧率高 — 检查网线质量、交换机端口、EMI 干扰
  • 抖动大 — 安装 DarraRT 驱动,隔离 CPU 核心
  • 偶尔超时 — 检查系统负载,关闭不必要的后台进程
  • DC 同步偏差大 — 使用 DarraRT 驱动降低抖动