跳到主要内容

Slave 属性与方法

通过 master.getSlave(n) 访问(1-based 索引)或 master.Slaves() 获取列表。

提示
  • PDO 输入输出(指针访问、字节数组、类型化访问等)请参见 PDO 输入输出 页面。
  • 从站事件请参见 事件 页面。
  • 从站诊断请参见 从站诊断 页面。

属性

类别属性类型读写说明
基本标识SlaveNumshort (public final)只读从站编号(1-based,不变值)
MasterIndexshort (public final)只读所属主站编号(不变值)
Name()String只读设备名称(从 EEPROM 读取)
DriveName()String只读驱动名称(从 SDO 0x1008 读取)
设备信息VendorId()int只读制造商 ID(从 SII EEPROM 读取)
VendorName()String只读制造商名称(从 ESI 文件读取)
ProductId()int只读产品 ID
RevId() / Revision()int只读修订版本号
SerialNumber()int只读序列号(从 SII EEPROM 读取)
Dtype()short只读设备类型标识(可转换为 EcDeviceType
HasMDP()boolean只读是否支持模块化设备配置文件(ETG.5001)
BlockLRW()boolean只读逻辑读写操作阻止标志
地址ConfigAddr()short只读物理配置地址
AliasAddress()short只读别名地址
Index()int只读从站索引(SlaveNum 别名)
状态State()EcState只读从站当前 EtherCAT 状态
ErrorCode()EcALState只读AL Status Code 错误码
IsLost()boolean只读从站是否丢失(断开连接)
拓扑TopologyByte()byte只读拓扑类型 (0=无链接, 1=端点, 2=中间, 3=分支, 4=交叉)
ParentStation()int只读父从站的站地址
ParentPort()byte只读父端口号
EntryPort()byte只读入口端口号
ActivePorts()byte只读激活端口位掩码
PhysicalType()byte只读物理端口类型
PDO 数据Ibits() / Obits()short只读输入/输出数据位数
Ibytes() / Obytes()int只读输入/输出数据字节数
Ioffset() / Ooffset()int只读输入/输出在过程数据中的偏移
Istartbit() / Ostartbit()byte只读输入/输出起始位
ESI/配置HasEsi()boolean只读是否已加载 ESI 文件
EsiVersion()String只读ESI 版本号
EEPROMEep8ByteAddressing()boolean只读EEPROM 寻址模式(true=8字节, false=4字节)
EepPDI()byte只读物理设备接口(PDI)类型
EbusCurrent()short只读E-bus 电流消耗(mA)
SIIindex()int只读SII EEPROM 配置索引
邮箱MbxProto()short只读支持的邮箱协议类型(MailboxType 位掩码)
MbxLength()short只读邮箱发送缓冲区大小
MbxReadLength()short只读邮箱接收缓冲区大小
MbxReadOffset() / MbxWriteOffset()short只读邮箱读/写偏移
MbxCount()byte只读邮箱协议计数器
协议详情CoEdetails()byte只读CoE 协议功能标志(SDO/PDO Assign/Complete Access 等)
EoEdetails()byte只读EoE 协议功能标志(发送帧/接收帧/IP 参数等)
FoEdetails()byte只读FoE 协议详情(来自 SII EEPROM)
SoEdetails()byte只读SoE 协议详情(来自 SII EEPROM)
FMMUFMMU0Function()byte只读FMMU0 功能类型(bit 0=输出, bit 1=输入)
FMMU1Function()byte只读FMMU1 功能类型
FMMU2Function()byte只读FMMU2 功能类型
FMMU3Function()byte只读FMMU3 功能类型
DCHasDC()boolean只读是否支持 DC,详见 DC 同步
DCActive()int只读DC 激活状态(0=禁用, 非0=已激活),详见 DC 同步
DCCycle0() / DCCycle1()int只读SYNC0/SYNC1 周期(纳秒),详见 DC 同步
DCShift()int只读相位偏移(纳秒),详见 DC 同步
PDelay()int只读帧从主站到达此从站的传播延迟(纳秒),详见 DC 同步
DCNext()int只读DC 下一个从站索引
DCPrevious()int只读DC 上一个从站索引
DCReceiveTimeA/B/C/D()int只读端口 A/B/C/D 接收时间(纳秒)
拓扑扩展SupportsFrameRepeat() / SupportsFrameRepeat(boolean)boolean读写是否支持帧重复功能(ETG.1500 5.4.3)
冗余RedundancyActivated()boolean只读冗余是否激活
PrimaryLinkBroken()boolean只读主线路断路
SecondaryLinkBroken()boolean只读冗余线路断路
配置Group() / Group(byte)byte读写从站分组号(0-7,0=默认组,必须在 SAFE_OP 前设置),详见 从站分组
IsOptional() / IsOptional(boolean)boolean读写可选从站标记,缺席时不影响 WKC 检查、不触发组离线告警(必须在 OP 前设置)

EcDeviceType 枚举

public enum EcDeviceType {
UNDEFINED(0), // 未定义
STATIC(1), // 静态设备,无 IO 映射,如 EK1100 耦合器
INPUT_NO_MAILBOX(2), // 输入设备(无邮箱)
OUTPUT_NO_MAILBOX(3), // 输出设备(无邮箱)
INPUT_WITH_MAILBOX(4), // 输入设备(有邮箱)
OUTPUT_WITH_MAILBOX(5), // 输出设备(有邮箱)
IO_NO_MAILBOX(6), // 输入输出设备(无邮箱)
IO_WITH_MAILBOX(7); // 输入输出设备(有邮箱)
}

EcTopologyType 枚举

public enum EcTopologyType {
NO_LINK(0), // 无链接
END_POINT(1), // 端点
LINE(2), // 中间节点(线性拓扑)
FORK(3), // 分支点
CROSS(4); // 交叉点
}

MailboxType 枚举

public enum MailboxType {
ERROR_MAILBOX(0x00), // 错误邮箱
ADS_OVER_ETHERCAT(0x01), // AoE
ETHERNET_OVER_ETHERCAT(0x02), // EoE
CANOPEN_OVER_ETHERCAT(0x03), // CoE
FILE_OVER_ETHERCAT(0x04), // FoE
SERVO_OVER_ETHERCAT(0x05), // SoE
VENDOR_OVER_ETHERCAT(0x0F); // VoE
}

子对象访问

方法返回类型说明
CoE()CoECANopen over EtherCAT
SoE()SoEServo over EtherCAT
FoE()FoEFile over EtherCAT
EoE()EoEEthernet over EtherCAT
AoE()AoEADS over EtherCAT
VoE()VoEVendor over EtherCAT
FSoE()FSoE功能安全
CiA402()CiA402CiA 402 驱动器
CiA401()CiA401CiA 401 I/O 模块
DC()DCDC 同步配置
PDO()PDOPDO 数据访问
SlavePdo()SlavePdo类型化 PDO 读写
Diagnostics()SlaveStats从站诊断统计
Topology()SlaveTopology从站拓扑信息
MDP()MDP模块化设备
Esi()EsiESI 信息
StartupParameters()StartupParameterList启动参数列表
延迟创建

所有子对象采用延迟创建模式,首次访问时自动实例化。

FMMU 属性

属性类型说明
FMMU0Function()byteFMMU0 功能类型
FMMU1Function()byteFMMU1 功能类型
FMMU2Function()byteFMMU2 功能类型
FMMU3Function()byteFMMU3 功能类型

SM/FMMU 查询方法

方法返回类型说明
GetWatchdogConfig()int[]看门狗配置 [分频器, PDI超时, PD超时],失败返回 null
GetWatchdogStatus()int[]看门狗状态 [过期, 计数器, 分频器, 超时],失败返回 null
备注

FMMU 功能类型请使用 FMMU0Function() ~ FMMU3Function() 单独获取。

操作方法

SetState(EcState targetState, int timeoutMs)

public boolean SetState(EcState targetState, int timeoutMs)
public boolean SetState(EcState targetState)

设置单个从站的 EtherCAT 状态,阻塞至转换完成或超时。无 timeoutMs 重载使用默认 3000ms。

参数:

  • targetState (EcState) — 目标状态(INIT / PRE_OP / SAFE_OP / OP)
  • timeoutMs (int) — 超时时间(毫秒)

返回值:

  • boolean — true 切换成功,false 失败或超时

示例:

Slave slave = master.getSlave(1);
if (!slave.SetState(EcState.PRE_OP)) {
System.out.println("从站 1 切换 PRE_OP 失败");
}
slave.SetState(EcState.OP, 5000);

SetWatchdog(int timeoutMs)

public boolean SetWatchdog(int timeoutMs)

设置过程数据看门狗超时(毫秒),0=禁用。

SetPdiWatchdog(int timeoutMs)

public boolean SetPdiWatchdog(int timeoutMs)

设置 PDI 看门狗超时(毫秒),0=禁用。

ConfigureDC(int sync0CycleNs, int sync1CycleNs, int shiftNs)

public void ConfigureDC(int sync0CycleNs, int sync1CycleNs, int shiftNs)
public void DisableDC()

配置/禁用 DC 同步。

提示

PDO 数据访问请见 PDO IO

寄存器读写

// 读取寄存器 (FPRD)
byte[] data = slave.readRegister(0x0130, 2); // 读寄存器

// 写入寄存器 (FPWR)
boolean ok = slave.writeRegister(0x0130, new byte[]{0x01, 0x00}); // 写寄存器
方法返回类型说明
readRegister(int offset, int size)byte[]读取从站寄存器,失败返回 null
writeRegister(int offset, byte[] data)boolean写入从站寄存器

SyncManager / FMMU 配置

// 配置 SyncManager: SM编号, 起始地址, 长度, 控制字节, 启用
slave.configureSyncManager(2, 0x1100, 128, 0x24, true); // SM2 输出

// 配置 FMMU: FMMU编号, 逻辑地址, 长度, 逻辑起始位, 逻辑结束位, 物理地址, 物理起始位, 类型, 启用
slave.configureFMMU(0, 0x00010000, 128, 0, 7, 0x1100, 0, 2, true);

// 启用/禁用输出 SyncManager
slave.enableOutputSyncManager();
slave.disableOutputSyncManager();
方法返回类型说明
configureSyncManager(int smIndex, int startAddr, int length, int control, boolean enable)boolean配置 SyncManager
configureFMMU(int fmmuIndex, int logicalAddr, int length, int logicalStartBit, int logicalEndBit, int physicalAddr, int physicalStartBit, int fmmuType, boolean enable)boolean配置 FMMU
enableOutputSyncManager()boolean启用输出 SyncManager
disableOutputSyncManager()boolean禁用输出 SyncManager

从站身份验证

// 获取从站身份信息
int[] identity = slave.GetSlaveIdentity(); // [VendorId, ProductCode, RevisionNo, SerialNo]

// 验证从站身份是否匹配
boolean match = slave.VerifySlaveIdentity(0x00000002, 0x03F03052, 0, 0, true, false);
方法返回类型说明
GetSlaveIdentity()int[]获取身份信息 [VendorId, ProductCode, RevisionNo, SerialNo],失败返回 null
VerifySlaveIdentity(int vendorId, int productCode, int revisionNo, int serialNo, boolean checkRev, boolean checkSerial)boolean验证身份是否匹配

ESM 超时配置

// 获取当前 ESM 状态转换超时配置
int[] timeouts = slave.GetEsmTimeouts(); // [IP, PS, SO, OS, SP, PI, BI, IB] (ms)

// 设置 ESM 状态转换超时
slave.SetEsmTimeouts(3000, 10000, 5000, 5000, 3000, 3000, 3000, 3000);
方法返回类型说明
GetEsmTimeouts()int[]获取 ESM 超时 [IP, PS, SO, OS, SP, PI, BI, IB] (毫秒),失败返回 null
SetEsmTimeouts(int ip, int ps, int so, int os, int sp, int pi, int bi, int ib)boolean设置 ESM 超时

热插拔 / 标志

// 热插拔重配置标志
boolean needsReconfig = slave.GetNeedsStartupReconfig();
slave.ClearNeedsStartupReconfig();

// OpOnly 标志 (仅在 OP 状态下交换数据)
boolean opOnly = slave.GetOpOnlyFlag();

// 错误确认 (清除 AL 错误)
slave.SetErrorAck(true);

// 设备仿真标志
boolean emulation = slave.GetDeviceEmulationFlag();
方法返回类型说明
GetNeedsStartupReconfig()boolean是否需要启动重配置(热插拔后)
ClearNeedsStartupReconfig()void清除启动重配置标志
GetOpOnlyFlag()boolean获取 OpOnly 标志
SetErrorAck(boolean setAck)boolean设置错误确认(清除 AL 错误)
GetDeviceEmulationFlag()boolean获取设备仿真标志

输出数据写入

// 写入输出数据
slave.writeOutput(new byte[]{0x0F, 0x00});

// 写入单字节
slave.writeOutputByte(0, (byte) 0x0F);
方法返回类型说明
writeOutput(byte[] data)void写入从站输出数据
writeOutputByte(int offset, byte value)void写入从站输出单字节

ESI 自动配置

// SM/FMMU/PDO 映射
boolean ok1 = slave.configureFromEsi();

// 综合配置 (SM + DC)
boolean ok2 = slave.ConfigByEsi();
方法返回类型说明
configureFromEsi()boolean从 ESI 文件自动配置 SM/FMMU/PDO 映射
ConfigByEsi()boolean综合配置 (AutoConfigureSM + DC 配置)

ESC 寄存器访问 (高级)

直接读写从站 ESC (EtherCAT Slave Controller) 寄存器,用于故障诊断自定义 ESC 操作底层调试。协议层走 FPRD/FPWR 数据报,自动 primary → secondary → APWR 三级回退。

高级 API

正常使用 SDK 时无需调用 — 状态切换 / PDO / 邮箱等流程 SDK 已自动配置寄存器。此 API 用于深度诊断特殊场景(例如读取错误计数器、强制端口策略、调试 ESI 烧写不生效等)。

寄存器定义见 ETG.1000.4 §6 / ETG.1000.6 §5(公开标准),例如:

寄存器说明
0x0000Type / Revision / Build(设备类型)
0x0030AL Control(主站发起状态请求)
0x0130AL Status(从站当前状态)
0x0134AL Status Code(错误码)
0x0300-0x030F端口 0-3 错误计数器
0x0400-0x043F看门狗配置 / 计数

readRegister(int offset, int size)

public byte[] readRegister(int offset, int size)

读取从站 ESC 寄存器(FPRD)。

参数:

  • offset (int) — 寄存器地址(例如 0x0130 = AL Status)
  • size (int) — 读取字节数(1 / 2 / 4 等)

返回值:

  • byte[] — 读取成功返回字节数组;失败(从站离线 / 超时)返回 null

writeRegister(int offset, byte[] data)

public boolean writeRegister(int offset, byte[] data)

写入从站 ESC 寄存器(FPWR)。

参数:

  • offset (int) — 寄存器地址
  • data (byte[]) — 写入数据

返回值:

  • boolean — 成功返回 true

示例:

Slave slave = master.getSlave(1);

// 读取 AL Status (0x0130, 2 字节)
byte[] alStatus = slave.readRegister(0x0130, 2);
if (alStatus != null) {
int state = (alStatus[0] & 0xFF) | ((alStatus[1] & 0xFF) << 8);
System.out.printf("AL Status = 0x%04X (state=%d, err=%b)%n",
state, state & 0x0F, (state & 0x10) != 0);
}

// 读取 AL Status Code (0x0134, 错误码)
byte[] alCode = slave.readRegister(0x0134, 2);
if (alCode != null) {
int code = (alCode[0] & 0xFF) | ((alCode[1] & 0xFF) << 8);
System.out.printf("AL Status Code = 0x%04X%n", code);
}

// 写 AL Control = 0x04 (请求 SafeOp)
slave.writeRegister(0x0030, new byte[]{0x04, 0x00});

EEPROM (SII) 访问

读写从站 SII EEPROM (Slave Information Interface, ETG.1000.6 §6)。EEPROM 存储 VendorID / ProductCode / RevisionNo / SerialNo / SyncManager / FMMU / PDO 映射 / Strings 等设备身份与配置信息。SDK 在 config_init 阶段已自动读取,应用一般无需直接访问。

危险操作

EEPROM 写入慎用 — 写错可能导致从站身份信息错乱,严重时永久 brick 从站, 需厂家工具恢复。仅在以下场景使用:

  • 烧写 alias 地址(Hot-Connect 别名)
  • 修复出厂数据被误覆盖
  • 厂商授权的固件 / 参数烧录

EEPROM 写需要从站处于 Init / PreOp 状态,OP 状态下写入会被拒绝。

EEPROM 大小通常 1 KB - 16 KB(按 word 寻址,1 word = 2 byte)。起始 8 word 为厂商基本信息,之后是 Category 链表(Strings / General / FMMU / SyncM / TxPdo / RxPdo / DC / End=0xFFFF)。

readEeprom(int byteOffset, int byteLength)

public byte[] readEeprom(int byteOffset, int byteLength)

读取从站 SII EEPROM 字节区域。SDK 自动处理 BUSY 轮询、字对齐。

参数:

  • byteOffset (int) — 起始字节偏移 (建议偶数对齐)
  • byteLength (int) — 读取字节数 (建议偶数)

返回值:

  • byte[]byteLength 字节数据; 参数非法返回 null, 读失败返回 null

writeEeprom(int byteOffset, byte[] data)

public boolean writeEeprom(int byteOffset, byte[] data)

写入从站 SII EEPROM 字节区域。byteOffsetdata.length 都必须是偶数。

参数:

  • byteOffset (int) — 起始字节偏移 (必须偶数)
  • data (byte[]) — 写入字节 (长度必须偶数)

返回值:

  • boolean — 全部 word 成功写入返回 true

示例:

Slave slave = master.getSlave(1);

// 读 vendor_id (EEPROM 字节偏移 0x10, 长度 4)
byte[] data = slave.readEeprom(0x10, 4);
if (data != null && data.length == 4) {
int vendorId = (data[0] & 0xFF) | ((data[1] & 0xFF) << 8)
| ((data[2] & 0xFF) << 16) | ((data[3] & 0xFF) << 24);
System.out.printf("VendorID = 0x%08X%n", vendorId);
}

// 读取头部 16 字节 (含 PDIControl/StationAlias 等)
byte[] header = slave.readEeprom(0, 16);

// 写 alias address (EEPROM 字节偏移 0x08)
// 必须从站处于 Init/PreOp 状态!
if (slave.State() == EcState.Init) {
slave.writeEeprom(0x08, new byte[]{0x01, 0x00}); // alias = 1
}
推荐用法
  • 首选: readEeprom / writeEeprom (按字节, 自动字对齐)
  • 次选: slave.VendorId() / ProductId() / SerialNumber() 等已封装属性

DL Port 端口控制

直接读写 ESC 的 DL Port Control 寄存器 (0x0101),用于端口故障注入测试冗余/环拓扑的手动诊断

高级 API

正常运行时无需调用。大部分用户应该通过订阅 addSlavePortLinkChangedListener 事件和读取 端口错误计数器 来诊断端口状态。仅在需要主动模拟端口故障(测试冗余切换)或排查特定端口问题时使用。

ESC 有 4 个物理端口 P0 / P1 / P2 / P3DL Port Control 寄存器的位定义如下:

DLPORT 值行为
0x00Auto — 所有端口由 ESC 自动管理(默认)
0x03关闭 P0
0x0C关闭 P1
0x30关闭 P2
0xC0关闭 P3

SDK 自动采用 primary → secondary → APWR 三级回退写入路径,即使 P0 关闭后仍能通过副网口/广播恢复。

WriteDLPort(byte value)

public boolean WriteDLPort(byte value)

写入从站 DL Port 控制寄存器(0x0101)。

参数:

  • value (byte) — DLPORT 值(见上表)

返回值:

  • boolean — 成功返回 true

ReadDLPort()

public byte ReadDLPort()

读取从站 DL Port 控制寄存器的当前值。

返回值:

  • byte — 当前 DLPORT 值;读取失败返回 0

示例:

// 模拟 P1 端口故障 (测试冗余切换)
boolean ok = slave.WriteDLPort((byte) 0x0C);
System.out.println("关闭 P1: " + (ok ? "成功" : "失败"));

// 读回确认
byte dlport = slave.ReadDLPort();
System.out.printf("当前 DLPORT = 0x%02X%n", dlport);

// 故障恢复后还原
slave.WriteDLPort((byte) 0x00); // 恢复 Auto
配合冗余诊断

关闭一个端口后,观察 addSlavePortLinkChangedListenermaster.Diagnostics().getAllBreakPoints() 验证冗余切换是否生效。

完整示例

Slave slave = master.getSlave(1);

// 基本信息
System.out.println("名称: " + slave.Name());
System.out.println("厂商: 0x" + Integer.toHexString(slave.VendorId()));
System.out.println("状态: " + slave.State());

// 子对象
CoE coe = slave.CoE();
CiA402 drv = slave.CiA402();
PDO pdo = slave.PDO();

// 可读写属性
slave.Group((byte) 1); // 分配到组 1
slave.IsOptional(true); // 标记为可选从站