跳到主要内容

Slave 属性与方法

通过 master.Slaves[n] 访问(0-based 索引)。​

提示
  • PDO 输入输出(金路径 slave.PDO.InputsMapping / OutputsMapping 映射一次钉页;CopyInputPdo / WriteOutputPdo 是快照)请参见 PDO 输入输出 页面。
  • 从站事件请参见 事件 页面。
  • 从站诊断请参见 从站诊断 页面。

属性​

类别属性类型读写说明
基本标识SlaveNumushort只读从站编号(1-based)
Indexint只读从站索引(SlaveNum 别名)
Namestring只读设备名称(从 EEPROM group_name 读取)
DriveNamestring只读驱动/设备名称(从 SII EEPROM device_name 读取)
设备信息VendorIduint只读制造商 ID(从 SII EEPROM 读取)
VendorNamestring?只读制造商名称(从 ESI 文件读取)
ProductIduint只读产品 ID
RevIduint只读修订版本号
Revisionuint只读RevId 别名(修订版本号)
SerialNumberuint只读序列号(从 SII EEPROM 读取)
HasMDPbool只读是否支持模块化设备配置文件(ETG.5001)
BlockLRWbool只读LRW 逻辑读写操作阻止标志
地址ConfigAddrushort只读物理配置地址
AliasAddressushort只读别名地址
状态StateEcState只读从站当前状态
StatusEcSlaveStatus只读从站完整状态(保留 Error 位,复合枚举),如 OpFault/SafeOpFault,推荐 UI/日志用,与 State 共享 wire 值仅类型不同
ErrorCodeEcALState只读错误码(AL Status Code)
IsLostbool只读从站是否丢失(事件确认的可靠离线状态)
HasEnteredOperationalbool只读本次运行该从站是否曾成功进入 OP(一旦进过即闩锁为 true,即使之后掉出)
DroppedFromOperationalbool只读是否"进过 OP 但当前已不在 OP"(运行中掉出 OP,热插拔可观测面)
诊断镜像WcContributedWcContribution只读该从站本周期对工作计数器(WKC)的贡献状态(薄读零帧,内核 per-slave 镜像),详见 WKC 贡献语义
AlStatusMirrorEcSlaveStatus只读内核 AL 状态镜像低字节(含 Error 位,薄读零帧,可 .Pretty()/.HasFault())
AlStatusCodeEcALState只读内核 AL 镜像高字节解码的 AL Status Code(无 Error 时返回 NoError,薄读零帧)
MailboxHealthEcMailboxHealth只读该从站邮箱健康度(Unknown/Healthy/Degraded,薄读零帧),让"在 OP 但邮箱半失效"可见
IsFreeRunDemotedbool只读该从站是否被迫从 DC 降级到 FreeRun 同步模式(薄读零帧,半失效根源观测点)
HealthDegradedCountuint只读该从站邮箱半失效连续累计计数(≈秒数,0=健康,内核每秒评估)
拓扑Topologybyte只读拓扑类型(0=无链接,1=端点,2=中间,3=分支,4=交叉),取值见 EcTopologyType
ParentStationushort只读父从站的站地址 (注: 实际是从站索引 1-based, 不是 station address; 0 表示父节点是主站)
ParentPortbyte只读父端口号
EntryPortbyte只读入口端口号
ActivePortsbyte只读激活端口位掩码
PhysicalTypebyte只读物理端口类型
ChildCountint只读子模块数量
PDO 数据Ibits / Obitsushort只读输入/输出数据位数
Ibytes / Obytesuint只读输入/输出数据字节数
InputsByteCount / OutputsByteCountint只读当前输入/输出过程映像映射字节数(未进 OP / 未映射为 0),详见 PDO 输入输出
Ioffset / Ooffsetuint只读输入/输出数据偏移
Istartbit / Ostartbitbyte只读输入/输出起始位
ESI/配置HasEsibool只读是否已加载 ESI 文件
Esinamestring?只读ESI 文件名
EsiVersionstring只读ESI 版本号(无 ESI 或解析失败为空串)
EsiMatchEsiMatchQuality只读ESI 文件与从站硬件的匹配质量(None/Exact/Fuzzy)
EsiMatchedRevisionuint只读ESI 中匹配到的 RevisionNo(EsiMatch=Fuzzy 时与 RevId 对比可知差异)
HasEsiDcSyncbool只读ESI 是否声明使用 DC 同步;启用 DC 前应同时检查 HasDC && HasEsiDcSync
ConfigByEsidynamic?只读从 ESI 文件获取的设备配置
EEPROMEep8ByteAddressingbool只读EEPROM 寻址模式(true=8字节, false=4字节)
EepPDIbyte只读物理设备接口(PDI)类型
EbusCurrentshort只读E-bus 电流消耗(mA)
邮箱MbxProtoMailboxProtocol只读支持的邮箱协议能力位图(SII mbx_proto:bit0=AoE,bit1=EoE,bit2=CoE,bit3=FoE,bit4=SoE,bit5=VoE)
MbxLengthushort只读邮箱发送缓冲区大小
MbxReadLengthushort只读邮箱接收缓冲区大小
MbxReadOffset / MbxWriteOffsetushort只读邮箱读/写偏移
MbxCountbyte只读邮箱计数器(邮箱帧头 Cnt 字段)
协议详情CoEdetailsEcCoEDetails只读CoE 协议功能标志(SDO/PDO Assign/Complete Access 等)
EoEdetailsEcEoEDetails只读EoE 协议功能标志(发送帧/接收帧/IP 参数等)
FoEdetailsbyte只读FoE 协议详情(来自 SII EEPROM)
SoEdetailsbyte只读SoE 协议详情(来自 SII EEPROM)
FMMUFMMU0Functionbyte只读FMMU0 功能类型(bit 0=输出, bit 1=输入)
FMMU1Functionbyte只读FMMU1 功能类型
FMMU2Functionbyte只读FMMU2 功能类型
FMMU3Functionbyte只读FMMU3 功能类型
DCHasDCbool只读是否支持 DC,详见 DC 同步
DCActiveushort只读DC 激活状态(0=禁用, 非0=已激活),详见 DC 同步
DCCycle0int只读SYNC0 周期(纳秒),详见 DC 同步
DCCycle1int只读SYNC1 周期(纳秒),详见 DC 同步
DCShiftint只读相位偏移(纳秒),详见 DC 同步
PropagationDelayint只读帧从主站到达此从站的传播延迟(纳秒),详见 DC 同步
PDelayint只读PropagationDelay 别名,传播延迟(纳秒)
DCNextushort只读DC 链中下一个从站的索引
DCPreviousushort只读DC 链中上一个从站的索引
DCParentPortint只读DC 父端口
DCReceiveTimeAint只读端口 A 接收时间(纳秒)
DCReceiveTimeBint只读端口 B 接收时间(纳秒)
DCReceiveTimeCint只读端口 C 接收时间(纳秒)
DCReceiveTimeDint只读端口 D 接收时间(纳秒)
拓扑扩展ChildrenList<Slave>只读子从站列表(配合 ChildCount 使用,导航拓扑树)
SupportsFrameRepeatbool只读是否支持帧重复功能(ETG.1500 5.4.3)
冗余RedundancyActivatedbool只读冗余是否激活
PrimaryLinkBrokenbool只读主链路是否断开
SecondaryLinkBrokenbool只读副链路是否断开
配置Groupbyte读写从站分组号(0-7,0=未分配,映射前自动归入组 1;有效 PDO 组 1-7,必须在 SAFE_OP 前设置),详见 从站分组
IsOptionalbool读写可选从站标记,缺席时不影响 WKC 检查、不触发组离线告警(必须在 OP 前设置)

MbxProto 返回 SII mbx_proto 能力位图([Flags] 枚举 MailboxProtocol:AoE=0x01、EoE=0x02、CoE=0x04、FoE=0x08、SoE=0x10、VoE=0x20),不是邮箱帧头的类型码 MailboxType(旧 MailboxType MbxProto 口径已废弃);判能力用 SupportsCoE() / SupportsFoE() / SupportsEoE() / SupportsSoE() / SupportsAoE() / SupportsVoE(),或直接位比 (slave.MbxProto & MailboxProtocol.CoE) != 0。

EcTopologyType / EcPortType 枚举值
public enum EcTopologyType : byte
{
NoLink = 0, // 无链接
EndPoint = 1, // 端点
Line = 2, // 中间节点(线性拓扑)
Fork = 3, // 分支点
Cross = 4 // 交叉点
}

public enum EcPortType : byte
{
NotUsed = 0, // 未使用
MII = 1, // MII
EBUS = 2, // EBUS
EBUSEnhanced = 3 // EBUS 增强型
}
MailboxType 枚举值
public enum MailboxType : ushort
{
ErrorMailbox = 0x00, // 错误邮箱
ADSOverEtherCAT = 0x01, // AoE
EthernetOverEtherCAT = 0x02, // EoE
CANopenOverEtherCAT = 0x03, // CoE
FileOverEtherCAT = 0x04, // FoE
ServoOverEtherCAT = 0x05, // SoE
VendorOverEtherCAT = 0x0F // VoE
}
EcCoEDetails 枚举值
[Flags]
public enum EcCoEDetails : byte
{
None = 0x00,
SDO = 0x01, // 支持 SDO
SDOInfo = 0x02, // 支持 SDO Info
PDOAssign = 0x04, // 支持 PDO Assign
PDOConfig = 0x08, // 支持 PDO Config
Startup = 0x10, // 支持 Startup
CompleteAccess = 0x20 // 支持 Complete Access
}
EcEoEDetails 枚举值
[Flags]
public enum EcEoEDetails : byte
{
None = 0x00,
SendFrame = 0x01, // 支持发送帧
ReceiveFrame = 0x02, // 支持接收帧
SetIPParam = 0x04, // 支持设置 IP 参数
GetIPParam = 0x08 // 支持获取 IP 参数
}
EcSlaveStatus 枚举值(完整状态,保留 Error 位)

State 只列基础 5 状态 + 一个 Error bit;EcSlaveStatus 把工业现场实际会出现的复合状态(如 OpFault = OP+Error)作为显式命名成员列出,避免出现 raw 数字(如 24)。0x10 是 ETG.1000.6 AL Status(0x0130)bit 4 = Error。

[Flags]
public enum EcSlaveStatus : byte
{
None = 0x00, // 离线或未读到 AL Status
Init = 0x01, // 初始化
PreOp = 0x02, // 预运行(邮箱可用,PDO 未启动)
Boot = 0x03, // 引导(FoE 固件升级)
SafeOp = 0x04, // 安全运行(PDO 输入有效,输出安全值)
OP = 0x08, // 运行(生产状态)
ErrorFlag = 0x10, // Error 标志位(与基础状态按位 OR)
InitFault = 0x11, // Init+Error
PreOpFault = 0x12, // PreOp+Error
BootFault = 0x13, // Boot+Error
SafeOpFault = 0x14, // SafeOp+Error
OpFault = 0x18 // OP+Error
}

扩展方法:BaseState()(取低 4 位)/ HasFault()(含 Error 位)/ IsRunning()(SafeOp 或 OP 且无 Error)/ IsOp()(OP 且无 Error)/ Pretty()(如 "OpFault (OP+Error)")。

WcContribution 枚举值(WKC 贡献状态)
public enum WcContribution : byte
{
NotContributed = 0x00, // 该从站此刻没在贡献 WKC(疑似掉站 / 热插拔恢复中)
Contributed = 0x01, // 该从站正常贡献 WKC(在总线上响应)
Unknown = 0xFF // 内核镜像未填充(尚未运行 PDO 循环 / 索引越界)— 诚实暴露,不臆造
}
EcMailboxHealth 枚举值(邮箱健康度)
public enum EcMailboxHealth : byte
{
Unknown = 0, // 未知 / 无邮箱 / 不在 OP — 邮箱健康度此时无意义
Healthy = 1, // 健康 — 在 OP 且邮箱可用
Degraded = 2 // 降级 — 在 OP 但邮箱半失效(CoE/SDO 可能阻塞)
}
EsiMatchQuality 枚举值(ESI 匹配质量)
public enum EsiMatchQuality
{
None = 0, // 未找到匹配的 ESI 文件 — 从站无法按 ESI 参数配置
Exact = 1, // VendorID+ProductCode+RevisionNo 全部精确相等 — 最安全
Fuzzy = 2 // VendorID+ProductCode 相同但 RevisionNo 不同 — 可能 PDO/SDO 不兼容
}

子对象​

类别属性类型读写说明
运行PDOSlavePdo只读PDO 数据访问器,详见 PDO 输入输出
EventsSlaveEvents只读从站级事件,详见 从站事件
DiagnosticsSlaveDiagnostics只读诊断信息访问器,详见 从站诊断
StartupStartupParameterList只读启动参数列表
协议CoECoEInstance?只读CANopen over EtherCAT,从站不支持时为 null
SoESoEInstance?只读Servo over EtherCAT,从站不支持时为 null
FoEFoEInstance?只读File over EtherCAT,从站不支持时为 null
EoEEoEInstance?只读Ethernet over EtherCAT,从站不支持时为 null
AoEAoEInstance?只读ADS over EtherCAT,从站不支持时为 null
VoEVoEInstance?只读Vendor over EtherCAT,从站不支持时为 null
FSoEFSoEInstance?只读Functional Safety over EtherCAT,从站不支持时为 null
扩展MDPMdpInstance?只读MDP 模块化设备,从站不支持时为 null
EsiEsiInstance只读ESI 文件加载器实例,提供 ESI 文件加载和解析功能
协议访问器是公开字段

CoE / SoE / FoE / EoE / AoE / VoE / FSoE 与 Events、SlaveNum 是公开字段(非属性),由 SDK 惰性初始化。应用侧只读取使用,不要赋值。

枚举描述​

所有枚举统一使用 .GetDescription() 扩展方法获取中文描述:

EcState state = slave.State;
string desc = state.GetDescription(); // "OP"

StateCiA402 driveState = slave.CoE.CiA402.StateDrive;
string driveDesc = driveState.GetDescription(); // "运行使能"

ModeCiA402 mode = slave.CoE.CiA402.OperationMode;
string modeDesc = mode.GetDescription(); // "周期同步位置 (CSP)"

FSoEState fsoeState = slave.FSoE.State;
string fsoeDesc = fsoeState.GetDescription(); // "数据交换"
统一规范

项目中所有枚举描述均通过 .GetDescription() 扩展方法获取,包括 EcState、EcALState、SDOError、FSoEState、FSoEError、StateCiA402、ModeCiA402 等。

诊断​

提示

从站诊断信息(通信异常率、冗余状态、DC 同步)通过 slave.Diagnostics 访问,详见 从站诊断。

ESI 方法​

SetEsiFile(string esiFileName)​

public bool SetEsiFile(string esiFileName)

设置从站使用的 ESI 文件。

返回值:

  • bool — 是否成功

ESI 实例​

通过 slave.Esi 访问,提供 ESI 文件的加载和解析功能。

Esi.Loading(string esiFilePath)​

public bool Loading(string esiFilePath)

加载 ESI 文件并提取启动参数(SDO 初始化配置)。

参数:

  • esiFilePath (string) — ESI XML 文件路径

返回值:

  • bool — 是否加载成功

示例:

bool ok = slave.Esi.Loading(@"C:\ESI\Beckhoff EL7xxx.xml");
if (ok)
Console.WriteLine($"已加载 {slave.Startup.Count} 个启动参数");

Esi.IsLoaded​

public bool IsLoaded { get; }

检查 ESI 文件是否已加载。

提示

EsiInstance 支持隐式布尔转换,可直接用于条件判断:

if (slave.Esi)  // 等同于 slave.HasEsi
Console.WriteLine("ESI 已加载");

过程数据看门狗​

SetWatchdog(uint timeoutMs)​

public bool SetWatchdog(uint timeoutMs)

设置从站过程数据看门狗超时。从站在超时时间内未收到过程数据帧时触发看门狗错误(ALStatusCode 0x001B)。

参数:

  • timeoutMs (uint) — 超时时间(毫秒),0 = 禁用,最大 6553ms

返回值:

  • bool — 是否成功
备注

应在 SafeOp 或 OP 状态下调用。

SetPdiWatchdog(int timeoutMs)​

public bool SetPdiWatchdog(int timeoutMs)

设置从站 PDI 看门狗超时。PDI 看门狗监控从站本地应用(微控制器固件)是否正常运行。

参数:

  • timeoutMs (int) — 超时时间(毫秒),0 = 禁用

返回值:

  • bool — 是否成功

示例:

slave.SetWatchdog(100);  // 100ms 超时
slave.SetWatchdog(0); // 禁用看门狗

GetWatchdogConfig()​

public (ushort Divider, ushort PdiTimeout, ushort PdTimeout)? GetWatchdogConfig()

读取从站看门狗当前配置。返回 null 表示读取失败。

返回值:

  • Divider (ushort) — 看门狗分频器
  • PdiTimeout (ushort) — PDI 看门狗超时值(分频器单位)
  • PdTimeout (ushort) — 过程数据看门狗超时值(分频器单位)

示例:

var config = slave.GetWatchdogConfig();
if (config.HasValue)
Console.WriteLine($"PD超时: {config.Value.PdTimeout} × {config.Value.Divider * 0.04}µs");

GetWatchdogStatus()​

public (bool Expired, byte Counter, ushort Divider, ushort TimeoutValue)? GetWatchdogStatus()

读取从站看门狗运行状态。返回 null 表示读取失败。

返回值:

  • Expired (bool) — 看门狗是否已过期
  • Counter (byte) — 看门狗计数器(过期累计次数)
  • Divider (ushort) — 当前分频器值
  • TimeoutValue (ushort) — 当前超时值

示例:

var status = slave.GetWatchdogStatus();
if (status?.Expired == true)
Console.WriteLine($"看门狗过期! 计数: {status.Value.Counter}");

状态切换​

SetState(EcState targetState, uint timeoutMs = 3000)​

public bool SetState(EcState targetState, uint timeoutMs = 3000)

设置从站 EtherCAT 状态(带超时)。用于手动恢复单个从站或将从站切换到指定状态。

参数:

  • targetState (EcState) — 目标状态
  • timeoutMs (uint) — 超时时间(毫秒),默认 3000ms

返回值:

  • bool — 是否成功
备注

状态切换遵循 EtherCAT 标准状态机流程,协议层自动处理中间状态。例如从 INIT 切换到 OP 会自动经过 PreOp → SafeOp → OP。

示例:

// 手动恢复单个从站到 OP
if (slave.State != EcState.OP)
slave.SetState(EcState.OP);

// 将从站切换到 Init(重置)
slave.SetState(EcState.Init, timeoutMs: 5000);

实时诊断镜像 (薄读零帧)​

WcContributed / AlStatusMirror / AlStatusCode / MailboxHealth / IsFreeRunDemoted / HealthDegradedCount 都是内核 per-slave 诊断缓存的薄读:每次访问直接读 native,不收发帧(零帧),不二次缓存,读到即此刻总线现实,无需手动刷新。

WKC 贡献语义​

WcContributed 反映此刻该从站是否真的在响应:

  • Contributed — 该从站正常贡献工作计数器(WKC),即聚合 WKC 完整(actual == expected,亦即缺口 WcDeficit == 0)时各从站逐字节比对都"满"。
  • NotContributed — 该从站此刻没在贡献 WKC(疑似掉站 / 热插拔恢复中)。这不是 master 故障,从站修复后内核镜像自然回到 Contributed。
  • Unknown(0xFF)— 内核镜像尚未填充(未运行 PDO 循环 / 索引越界),诚实暴露,不臆造为"已贡献"。
R1 可靠性铁律

本属性仅"如实反映总线现实",不参与任何 WKC 篡改 / 迁就逻辑。逐从站贡献位是聚合 WKC 缺口(expected - actual)的逐站分解:聚合满则该站贡献,缺口大于 0 表示有从站此刻未贡献,应报警 + 诊断,不下调 expected、不停 OP。

示例:

foreach (var slave in master.Slaves)
{
if (slave.WcContributed == WcContribution.NotContributed)
Console.WriteLine($"从站 {slave.SlaveNum} 此刻未贡献 WKC(疑似掉站),AL={slave.AlStatusCode}");

if (slave.MailboxHealth == EcMailboxHealth.Degraded)
Console.WriteLine($"从站 {slave.SlaveNum} 在 OP 但邮箱半失效,已持续 {slave.HealthDegradedCount}s");

// AL 镜像可读为可读字符串
Console.WriteLine($"从站 {slave.SlaveNum}: {slave.AlStatusMirror.Pretty()}");
}

RecoverMailboxHealth()​

public bool RecoverMailboxHealth()

手动触发该从站邮箱半失效修复。通常无需手动调用 —— 内核在半失效持续 ≥3 秒后会自动修复。仅在上层希望立即介入时使用。通讯异常时返回 false,不抛未处理异常。

返回值:

  • bool — true=已触发修复流程;false=参数无效 / 从站当前无需修复

ESC 寄存器访问 (高级)​

直接读写从站 ESC (EtherCAT Slave Controller) 寄存器,用于故障诊断、自定义 ESC 操作、底层调试。冗余/双网口部署下自动选用可达路径。

高级 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(ushort, byte[], uint)​

public bool ReadRegister(ushort registerAddress, byte[] data, uint length)

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

参数:

  • registerAddress (ushort) — 寄存器地址(例如 0x0130 = AL Status)
  • data (byte[]) — 接收缓冲区,长度 ≥ length
  • length (uint) — 读取字节数(1 / 2 / 4 等)

返回值:

  • bool — 成功返回 true,失败(从站离线 / 超时)返回 false

WriteRegister(ushort, byte[], uint)​

public bool WriteRegister(ushort registerAddress, byte[] data, uint length)

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

参数:

  • registerAddress (ushort) — 寄存器地址
  • data (byte[]) — 写入数据
  • length (uint) — 字节数

返回值:

  • bool — 成功返回 true

示例:

var slave = master.Slaves[0];

// 读取 AL Status (0x0130, 2 字节)
byte[] alStatus = new byte[2];
if (slave.ReadRegister(0x0130, alStatus, 2))
{
ushort state = (ushort)(alStatus[0] | (alStatus[1] << 8));
Console.WriteLine($"AL Status = 0x{state:X4} (state={state & 0x0F}, err={(state & 0x10) != 0})");
}

// 读取 AL Status Code (0x0134, 错误码)
byte[] alCode = new byte[2];
slave.ReadRegister(0x0134, alCode, 2);
ushort code = (ushort)(alCode[0] | (alCode[1] << 8));
Console.WriteLine($"AL Status Code = 0x{code:X4}");

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

EEPROM (SII) 访问​

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

通过 slave.Sii 子对象(SiiInstance)访问 EEPROM 完整 API。

危险操作

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

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

每个 word 内部自动取得主站持有并在写后还给 PDI,免手动 Sii.Acquire() / Sii.Release();显式 Sii.Acquire() / Sii.Release() 用于批量写整段持有,避免 PDI 中途抢回。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 轮询和字对齐, 推荐应用层优先使用此高层 API。失败不再静默返回空数组:参数非法或某个 word 未回都会抛异常, 调用方不会把「读到空」误当成「读失败」;不想用异常请改用 TryReadEeprom。

参数:

  • byteOffset (int) — EEPROM 字节偏移 (建议偶数对齐, 奇数自动按低字节对齐)
  • byteLength (int) — 读取字节数 (建议偶数, 奇数末尾自动取低字节)

返回值:

  • byte[] — 读取到的字节数据

byteOffset < 0 或 byteLength <= 0 抛 ArgumentOutOfRangeException;某个 word 未回抛 InvalidOperationException(消息含失败的 word 地址)。

TryReadEeprom(int byteOffset, int byteLength, out byte[] data, out int failedWordAddress)​

public bool TryReadEeprom(int byteOffset, int byteLength, out byte[] data, out int failedWordAddress)

ReadEeprom 的无异常版本, 供不用 try/catch 的调用方区分成功与失败。

参数:

  • byteOffset (int) — EEPROM 字节偏移 (建议偶数对齐, 奇数自动按低字节对齐)
  • byteLength (int) — 读取字节数 (建议偶数, 奇数末尾自动取低字节)
  • data (out byte[]) — 成功时输出读取到的字节数据;失败时为空数组
  • failedWordAddress (out int) — 失败时输出未回的 word 地址;成功时为 0xFFFF

返回值:

  • bool — 全部 word 读取成功返回 true;参数非法或任一 word 读失败返回 false

WriteEeprom(int byteOffset, byte[] data)​

public bool WriteEeprom(int byteOffset, byte[] data)

写入从站 SII EEPROM 字节区域。byteOffset 与 data.Length 都必须是偶数。

参数:

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

返回值:

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

示例:

var slave = master.Slaves[0];

// 读 vendor_id (EEPROM 字节偏移 0x10, 长度 4)
byte[] data = slave.ReadEeprom(0x10, 4);
if (data.Length == 4)
{
uint vendorId = BitConverter.ToUInt32(data, 0);
Console.WriteLine($"VendorID = 0x{vendorId:X8}");
}

// 写 alias address (EEPROM 字节偏移 0x08, 2 字节)
// 必须从站处于 Init/PreOp 状态!
if (slave.State == EcState.Init)
{
slave.WriteEeprom(0x08, new byte[] { 0x01, 0x00 });
}
高层 API vs 低层 SII API
  • 首选: ReadEeprom / WriteEeprom (按字节, 自动字对齐, 自动接管/归还 EEPROM)
  • 次选: slave.VendorId / ProductId / SerialNumber 等已封装属性
  • 高级用法 (按需): 下方 Sii.ReadWord / WriteWord / Acquire / Release / FindCategory / ReadCategory / EnumerateCategories / GetStrings / GetGeneralInfo 等低层 API, 用于枚举 Category / 读 PDO 映射原始字节 / 烧写 alias 等场景

高级用法: Sii 低层 API​

下列 slave.Sii.* 子对象 API 提供 word 级、Category 级、控制权管理等更精细的控制。普通应用建议使用上方 ReadEeprom / WriteEeprom。

Sii.ReadWord(ushort, out ushort)​

public bool ReadWord(ushort wordAddr, out ushort value)

读取单个 EEPROM word。

参数:

  • wordAddr (ushort) — word 偏移(不是字节)
  • value (out ushort) — 读出的 16-bit 值

返回值:

  • bool — 成功返回 true

Sii.WriteWord(ushort, ushort)​

public bool WriteWord(ushort wordAddr, ushort value)

写入单个 EEPROM word(带 PDI 切换保护,写后自动归还)。

Sii.Acquire() / Sii.Release()​

public bool Acquire()   // 强制主站接管 EEPROM
public bool Release() // 归还 EEPROM 控制权给 PDI

Sii.IsHeldByPdi​

public bool IsHeldByPdi { get; }

EEPROM 控制权归属:false = 主站掌控,true = PDI(从站本地固件)掌控。

Sii.FindCategory(SiiCategory)​

public (uint byteOffset, uint byteSize)? FindCategory(SiiCategory cat)

查找指定 Category 的字节偏移与大小,返回 null 表示该 Category 不存在。

Sii.ReadCategory(SiiCategory, int)​

public byte[]? ReadCategory(SiiCategory cat, int maxBytes = 4096)

读取整个 Category 数据为字节数组。

Sii.EnumerateCategories(int)​

public SiiCategory[] EnumerateCategories(int max = 64)

枚举从站所有 Category 类型。

Sii.GetStrings(int) / Sii.GetStringByIndex(byte, int)​

public List<string> GetStrings(int maxBufBytes = 4096)
public string GetStringByIndex(byte stringIndex, int maxBytes = 256)

读取 Strings Category 并解析为字符串列表,或按索引(1-based)取单个字符串(GroupName / DeviceName / ImageName 等)。

Sii.GetGeneralInfo()​

public SiiGeneralInfo? GetGeneralInfo()

读取并解析 General Category(type = 30)为结构化信息(CoeDetails / FoeDetails / EoeDetails / SoeDetails / EbusCurrentMa / PhysicalPort 等)。

SiiCategory 枚举(ETG.1000.6 Table 17)
public enum SiiCategory : ushort
{
Strings = 10,
DataTypes = 20,
General = 30,
FMMU = 40,
SyncM = 41,
TxPdo = 50,
RxPdo = 51,
DC = 60,
End = 0xFFFF,
}

Sii 低层用法示例:

var slave = master.Slaves[0];

// 枚举 Category
foreach (var cat in slave.Sii.EnumerateCategories())
Console.WriteLine($" Category: {cat}");

// 读 General Category 结构化信息
var info = slave.Sii.GetGeneralInfo();
if (info != null)
Console.WriteLine($"E-bus 电流: {info.EbusCurrentMa} mA, " +
$"CoE Complete Access: {info.SupportsCompleteAccess}");

// 读 PDO 映射 Category 字节数组 (TxPdo)
byte[]? txPdo = slave.Sii.ReadCategory(SiiCategory.TxPdo);
Console.WriteLine($"TxPdo Category: {txPdo?.Length ?? 0} 字节");

// word 级写入; 必须从站处于 Init/PreOp 状态
// 此处 Sii.Acquire()/Sii.Release() 为批量写整段持有示例(单次写免手动)
if (slave.State == EcState.Init && slave.Sii.Acquire())
{
slave.Sii.WriteWord(0x04, 0x0001); // alias = 1
slave.Sii.WriteWord(0x05, 0x0000); // 保留字段
slave.Sii.Release();
}

Startup 配置​

类别属性类型读写说明
启动配置StartupStartupParameterList只读启动参数列表
ShouldWritePDOAssignmentbool读写启动时是否写入 PDO Assignment,默认 true
ShouldWritePDOConfigurationbool读写启动时是否写入 PDO Configuration,默认 false
SupportsCompleteAccessbool读写从站是否支持 SDO Complete Access

AutoStartup() / AutoStartupFromESI() / AutoStartupFromMDP() / AutoStartupFromSM()​

public bool AutoStartup()
public bool AutoStartupFromESI(string esiFilePath)
public bool AutoStartupFromMDP()
public bool AutoStartupFromSM()

对从站执行自动启动配置。AutoStartup() 会自动检测 ESI/MDP/SM 并生成参数;AutoStartupFromESI(esiFilePath) 从指定 ESI 文件生成参数(文件不存在或无 Startup 配置时返回 false)。

SetConfigSourceENI() / SetConfigSourceDENI()​

public void SetConfigSourceENI()
public void SetConfigSourceDENI()

设置从站配置来源。

RefreshPDOStartupParameters()​

public int RefreshPDOStartupParameters()

刷新 PDO 启动参数(重新从当前配置生成 PDO 映射参数)。

StartupParameterList 方法(通过 slave.Startup 访问):

  • Add(StartupParameter param) — 添加启动参数
  • AddParameter(index, subIndex, data, ...) — 添加启动参数(显式参数)
  • Remove(index, subIndex) — 移除启动参数
  • Clear() — 清除所有启动参数

单个参数用条目自己的 Apply(slave) 应用(StartupParameter 上的方法,不是列表方法)。

相关结构:

  • IP — Init → PreOp,默认 AfterTransition
  • PS — PreOp → SafeOp,默认 BeforeTransition
  • SO — SafeOp → Op,默认 BeforeTransition
  • OS — Op → SafeOp,默认 AfterTransition
  • SP — SafeOp → PreOp,默认 AfterTransition
  • PI — PreOp → Init,默认 BeforeTransition

示例:

slave.Startup.Add(new StartupParameter
{
Index = 0x1C12, SubIndex = 0,
Data = new byte[] { 0 },
TransitionEnum = StartupTransition.PS, Priority = 10
});