跳到主要内容

Slave 属性与方法

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

提示
  • PDO 输入输出(结构体映射、字节数组、索引访问等)请参见 PDO 输入输出 页面。
  • 从站事件请参见 事件 页面。
  • 从站诊断请参见 从站诊断 页面。

属性

类别属性类型读写说明
基本标识SlaveNumushort只读从站编号(1-based)
Indexint只读从站索引(SlaveNum 别名)
Namestring只读设备名称(从 EEPROM group_name 读取)
DriveNamestring只读驱动/设备名称(从 SII EEPROM device_name 读取)
设备信息VendorIduint只读制造商 ID(从 SII EEPROM 读取)
VendorNamestring?只读制造商名称(从 ESI 文件读取)
ProductIduint只读产品 ID
RevIduint只读修订版本号
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=交叉)
ParentStationushort只读父从站的站地址 (注: 实际是从站索引 1-based, 不是 station address; 0 表示父节点是主站)
ParentPortbyte只读父端口号
EntryPortbyte只读入口端口号
ActivePortsbyte只读激活端口位掩码
PhysicalTypebyte只读物理端口类型
ChildCountint只读子模块数量
PDO 数据Ibits / Obitsushort只读输入/输出数据位数
Ibytes / Obytesuint只读输入/输出数据字节数
Ioffset / Ooffsetuint只读输入/输出数据偏移
Istartbit / Ostartbitbyte只读输入/输出起始位
ESI/配置HasEsibool只读是否已加载 ESI 文件
Esinamestring?只读ESI 文件名
EsiVersionstring只读ESI 版本号
ConfigByEsidynamic?只读从 ESI 文件获取的设备配置
EEPROMEep8ByteAddressingbool只读EEPROM 寻址模式(true=8字节, false=4字节)
EepPDIbyte只读物理设备接口(PDI)类型
EbusCurrentshort只读E-bus 电流消耗(mA)
邮箱MbxProtoMailboxType只读支持的邮箱协议类型(位掩码)
MbxLengthushort只读邮箱发送缓冲区大小
MbxReadLengthushort只读邮箱接收缓冲区大小
MbxReadOffset / MbxWriteOffsetushort只读邮箱读/写偏移
MbxCountbyte只读邮箱协议计数器
协议详情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=默认组,必须在 SAFE_OP 前设置),详见 从站分组
IsOptionalbool读写可选从站标记,缺席时不影响 WKC 检查、不触发组离线告警(必须在 OP 前设置)
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 可能阻塞)
}
C# 特有语法糖

C# 可用 var (vendor, product, revision) = slave; 一行元组解构取出 VendorId / ProductId / RevId, 也支持 4 元组追加 Serial 或运行态 3 元组 (Index, Name, State). 详见 元组解构 (Deconstruct).

身份缓存查表场景可用 slave.GetIdentityKey() 返回的 readonly record struct SlaveIdentityKey, 配合 with { Revision = 0 } 派生 fuzzy key. 详见 不可变身份记录.

子对象

属性类型说明
PDOSlavePdoPDO 数据访问器,详见 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
EsiEsiInstanceESI 文件加载器实例,提供 ESI 文件加载和解析功能

枚举描述

所有枚举统一使用 .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() 扩展方法获取,包括 EcStateEcALStateSDOErrorFSoEStateFSoEErrorStateCiA402ModeCiA402 等。

诊断

提示

从站诊断信息(通信异常率、冗余状态、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
  • Unknown0xFF)— 内核镜像尚未填充(未运行 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,不抛未处理异常。

返回值:

  • booltrue=已触发修复流程;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 别名)
  • 修复出厂数据被误覆盖
  • 厂商授权的固件 / 参数烧录

写入前必须先调用 Acquire() 接管 EEPROM, 写入完成后调用 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。

参数:

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

返回值:

  • byte[] — 读取的字节数据, 失败或参数非法返回空数组

WriteEeprom(int byteOffset, byte[] data)

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

写入从站 SII EEPROM 字节区域。byteOffsetdata.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 级写入 (Sii.Acquire/Release 手动管理 EEPROM 接管)
// 必须从站处于 Init/PreOp 状态!
if (slave.State == EcState.Init && slave.Sii.Acquire())
{
slave.Sii.WriteWord(0x04, 0x0001); // alias = 1
slave.Sii.Release();
}

DL Port 端口控制

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

高级 API

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

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

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

即使 P0 关闭后, SDK 仍可通过副网口/广播路径恢复访问。

WriteDLPort(byte value)

public bool WriteDLPort(byte value)

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

参数:

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

返回值:

  • bool — 成功返回 true

ReadDLPort()

public byte ReadDLPort()

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

返回值:

  • byte — 当前 DLPORT 值

示例:

// 模拟 P1 端口故障 (测试冗余切换)
bool ok = slave.WriteDLPort(0x0C);
Console.WriteLine($"关闭 P1: {(ok ? "成功" : "失败")}");

// 读回确认
byte dlport = slave.ReadDLPort();
Console.WriteLine($"当前 DLPORT = 0x{dlport:X2}");

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

关闭一个端口后,观察 master.Events.SlavePortLinkChangedmaster.Diagnostics.BreakPoint 验证冗余切换是否生效。

Startup 配置

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

AutoStartup() / AutoStartupFromMDP() / AutoStartupFromSM()

public bool AutoStartup()
// AutoStartupFromESI(string esiFilePath) - ESI-based startup is implemented in the runtime but
// is intentionally omitted from the public API documentation (internal/advanced usage).
public bool AutoStartupFromMDP()
public bool AutoStartupFromSM()

对从站执行自动启动配置。AutoStartup() 会自动检测 ESI/MDP/SM 并生成参数。

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, transition, writeTiming) — 应用启动参数到从站

示例:

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

相关结构:

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