Slave 属性与方法
通过 master[n] 或 master.slave(n) 访问(1-based 索引)。
属性
| 类别 | 属性 | 类型 | 读写 | 说明 |
|---|---|---|---|---|
| 基本标识 | slave_num | int | 只读 | 从站编号(1-based) |
| index | int | 只读 | 从站索引(slave_num 别名) | |
| name | str | 只读 | 设备名称(从 EEPROM group_name 读取) | |
| drive_name | str | 只读 | 驱动/设备名称(从 SDO 0x1008 读取) | |
| 设备信息 | vendor_id | int | 只读 | 制造商 ID(从 SII EEPROM 读取) |
| vendor_name | str | None | 只读 | 制造商名称(从 ESI 文件读取) | |
| product_id | int | 只读 | 产品 ID | |
| rev_id | int | 只读 | 修订版本号 | |
| serial_number | int | 只读 | 序列号(从 SII EEPROM 读取) | |
| dtype | int | 只读 | 设备类型标识(可转换为 EcDeviceType) | |
| has_mdp | bool | 只读 | 是否支持模块化设备配置文件(ETG.5001) | |
| block_lrw | bool | 只读 | LRW 逻辑读写操作阻止标志 | |
| 地址 | config_addr | int | 只读 | 物理配置地址 |
| alias_address | int | 只读 | 别名地址 | |
| 状态 | state | EcState | 只读 | 从站当前状态 |
| error_code | EcALState | 只读 | 错误码 | |
| is_lost | bool | 只读 | 从站是否丢失(断开连接) | |
| 拓扑 | topology | int | 只读 | 拓扑类型 (0=无链接, 1=端点, 2=中间, 3=分支, 4=交叉) |
| parent_station | int | 只读 | 父从站的站地址 | |
| parent_port | int | 只读 | 父端口号 | |
| entry_port | int | 只读 | 入口端口号 | |
| active_ports | int | 只读 | 激活端口位掩码 | |
| physical_type | int | 只读 | 物理端口类型 | |
| child_count | int | 只读 | 子模块数量 | |
| PDO 数据 | ibits / obits | int | 只读 | 输入/输出数据位数 |
| ibytes / obytes | int | 只读 | 输入/输出数据字节数 | |
| ioffset / ooffset | int | 只读 | 输入/输出在 IOmap 中的偏移 | |
| istartbit / ostartbit | int | 只读 | 输入/输出起始位 | |
| ESI/配置 | has_esi | bool | 只读 | 是否已加载 ESI 文件 |
| esi_name | str | None | 只读 | ESI 文件名 | |
| esi_version | str | 只读 | ESI 版本号 | |
| config_by_esi | object | None | 只读 | 从 ESI 文件获取的设备配置 | |
| EEPROM | eep_8byte_addressing | bool | 只读 | EEPROM 寻址模式(True=8字节, False=4字节) |
| eep_pdi | int | 只读 | 物理设备接口(PDI)类型 | |
| ebus_current | int | 只读 | E-bus 电流消耗(mA) | |
| sii_index | int | 只读 | SII EEPROM 配置索引 | |
| 邮箱 | mbx_proto | int | 只读 | 支持的邮箱协议类型(MailboxType 位掩码) |
| mbx_length | int | 只读 | 邮箱发送缓冲区大小 | |
| mbx_read_length | int | 只读 | 邮箱接收缓冲区大小 | |
| mbx_read_offset / mbx_write_offset | int | 只读 | 邮箱读/写偏移 | |
| mbx_count | int | 只读 | 邮箱协议计数器 | |
| 协议详情 | coe_details | int | 只读 | CoE 协议功能标志(EcCoEDetails 位掩码) |
| eoe_details | int | 只读 | EoE 协议功能标志(EcEoEDetails 位掩码) | |
| foe_details | int | 只读 | FoE 协议详情(来自 SII EEPROM) | |
| soe_details | int | 只读 | SoE 协议详情(来自 SII EEPROM) | |
| FMMU | fmmu0_function | int | 只读 | FMMU0 功能类型(bit 0=输出, bit 1=输入) |
| fmmu1_function | int | 只读 | FMMU1 功能类型 | |
| fmmu2_function | int | 只读 | FMMU2 功能类型 | |
| fmmu3_function | int | 只读 | FMMU3 功能类型 | |
| DC | has_dc | bool | 只读 | 是否支持 DC,详见 DC 同步 |
| dc_active | int | 只读 | DC 激活状态(0=禁用, 非0=已激活),详见 DC 同步 | |
| dc_cycle0 | int | 只读 | SYNC0 周期(纳秒),详见 DC 同步 | |
| dc_cycle1 | int | 只读 | SYNC1 周期(纳秒),详见 DC 同步 | |
| dc_shift | int | 只读 | 相位偏移(纳秒),详见 DC 同步 | |
| dc_next | int | 只读 | DC 链中下一个从站的索引 | |
| dc_previous | int | 只读 | DC 链中上一个从站的索引 | |
| dc_parent_port | int | 只读 | DC 父端口号 | |
| dc_receive_time_a | int | 只读 | 端口 A 接收时间(纳秒) | |
| dc_receive_time_b | int | 只读 | 端口 B 接收时间(纳秒) | |
| dc_receive_time_c | int | 只读 | 端口 C 接收时间(纳秒) | |
| dc_receive_time_d | int | 只读 | 端口 D 接收时间(纳秒) | |
| propagation_delay | int | 只读 | 帧从主站到达此从站的传播延迟(纳秒),详见 DC 同步 | |
| p_delay | int | 只读 | 传播延迟(纳秒,propagation_delay 别名) | |
| 拓扑扩展 | children | List[Slave] | 只读 | 子从站列表(配合 child_count 使用,导航拓扑树) |
| supports_frame_repeat | bool | 读写 | 是否支持帧重复功能(ETG.1500 5.4.3) | |
| 冗余 | redundancy_activated | bool | 只读 | 冗余是否已激活 |
| primary_link_broken | bool | 只读 | 主线路是否断路 | |
| secondary_link_broken | bool | 只读 | 冗余线路是否断路 | |
| 配置 | group | int | 读写 | 从站分组号(0-7,0=默认组,必须在 SAFE_OP 前设置),详见 从站分组 |
| is_optional | bool | 读写 | 可选从站标记,缺席时不影响 WKC 检查、不触发组离线告警(必须在 OP 前设置) | |
| Startup | should_write_pdo_assignment | bool | 读写 | 启动时是否写入 PDO Assignment,默认 True |
| should_write_pdo_configuration | bool | 读写 | 启动时是否写入 PDO Configuration,默认 False | |
| supports_complete_access | bool | 读写 | 从站是否支持 SDO Complete Access |
EcDeviceType 枚举值
class EcDeviceType(IntEnum):
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 / EcPortType 枚举值
class EcTopologyType(IntEnum):
NO_LINK = 0 # 无链接
END_POINT = 1 # 端点
LINE = 2 # 中间节点(线性拓扑)
FORK = 3 # 分支点
CROSS = 4 # 交叉点
class EcPortType(IntEnum):
NOT_USED = 0 # 未使用
MII = 1 # MII
EBUS = 2 # EBUS
EBUS_ENHANCED = 3 # EBUS 增强型
MailboxType 常量
class MailboxType(IntEnum):
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
EcCoEDetails 常量
class EcCoEDetails(IntFlag):
NONE = 0x00
SDO = 0x01 # 支持 SDO
SDO_INFO = 0x02 # 支持 SDO Info
PDO_ASSIGN = 0x04 # 支持 PDO Assign
PDO_CONFIG = 0x08 # 支持 PDO Config
STARTUP = 0x10 # 支持 Startup
COMPLETE_ACCESS = 0x20 # 支持 Complete Access
EcEoEDetails 常量
class EcEoEDetails(IntFlag):
NONE = 0x00
SEND_FRAME = 0x01 # 支持发送帧
RECEIVE_FRAME = 0x02 # 支持接收帧
SET_IP_PARAM = 0x04 # 支持设置 IP 参数
GET_IP_PARAM = 0x08 # 支持获取 IP 参数
子对象
| 属性 | 类型 | 说明 |
|---|---|---|
| pdo | SlavePdo | PDO 数据访问器,详见 PDO 输入输出 |
| events | SlaveEvents | 从站级事件,详见 从站事件 |
| diagnostics | SlaveDiagnostics | 诊断信息访问器,详见 从站诊断 |
| startup | StartupParameterList | 启动参数列表 |
| coe | CoEInstance | None | CANopen over EtherCAT,从站不支持时为 None |
| soe | SoEInstance | None | Servo over EtherCAT,从站不支持时为 None |
| foe | FoEInstance | None | File over EtherCAT,从站不支持时为 None |
| eoe | EoEInstance | None | Ethernet over EtherCAT,从站不支持时为 None |
| aoe | AoEInstance | None | ADS over EtherCAT,从站不支持时为 None |
| voe | VoEInstance | None | Vendor over EtherCAT,从站不支持时为 None |
| fsoe | FSoEInstance | None | Functional Safety over EtherCAT,从站不支持时为 None |
| mdp | MdpInstance | None | MDP 模块化设备,从站不支持时为 None |
| esi | EsiInstance | ESI 文件加载器实例,提供 ESI 文件加载和解析功能 |
枚举描述
所有枚举统一使用 .description 属性获取中文描述:
state = slave.state
desc = state.description # "OP"
# CiA402 通过 slave.cia402 访问 (从站不支持 CoE 时为 None)
cia = master[1].cia402
if cia is not None:
state = cia.state # 驱动器状态
项目中所有枚举描述均通过 .description 属性获取,包括 EcState、EcALState、SDOError、FSoEState、FSoEError、StateCiA402、ModeCiA402 等。
硬件信息查询
以下方法尚未实现,将在后续版本中添加:
get_fmmus() -> List[EcFmmu]— 获取从站 FMMU 配置数组get_sync_managers() -> List[EcSm]— 获取从站 SyncManager 配置数组get_sync_manager_types() -> List[int]— 获取从站 SyncManager 类型数组
诊断
从站诊断信息(通信异常率、冗余状态、DC 同步)通过 slave.diagnostics 访问,详见 从站诊断。
ESI 方法
set_esi_file(esi_file_name)
def set_esi_file(esi_file_name: str) -> bool
设置从站使用的 ESI 文件。
返回值:
bool— 是否成功
过程数据看门狗
set_watchdog(timeout_ms)
def set_watchdog(timeout_ms: int) -> bool
设置从站过程数据看门狗超时。从站在超时时间内未收到过程数据帧时触发看门狗错误(ALStatusCode 0x001B)。
参数:
timeout_ms(int) — 超时时间(毫秒),0 = 禁用,最大 6553ms
返回值:
bool— 是否成功
应在 SafeOp 或 OP 状态下调用。
set_pdi_watchdog(timeout_ms)
def set_pdi_watchdog(timeout_ms: int) -> bool
设置从站 PDI 看门狗超时。PDI 看门狗监控从站本地应用(微控制器固件)是否正常运行。
参数:
timeout_ms(int) — 超时时间(毫秒),0 = 禁用
返回值:
bool— 是否成功
示例:
slave.set_watchdog(100) # 100ms 超时
slave.set_watchdog(0) # 禁用看门狗
watchdog_config
@property
def watchdog_config(self) -> Optional[dict]
读取从站看门狗当前配置。返回 None 表示读取失败。
返回值:
Optional[dict]— 看门狗配置字典,包含以下键:divider(int) — 看门狗分频器pdi_timeout(int) — PDI 看门狗超时值(分频器单位)pd_timeout(int) — 过程数据看门狗超时值(分频器单位)
示例:
config = slave.watchdog_config
if config is not None:
print(f"PD超时: {config['pd_timeout']} × {config['divider'] * 0.04}µs")
watchdog_status
@property
def watchdog_status(self) -> Optional[dict]
读取从站看门狗运行状态。返回 None 表示读取失败。
返回值:
Optional[dict]— 看门狗状态字典,包含以下键:status(int) — 看门狗状态值counter(int) — 看门狗计数器(过期累计次数)divider(int) — 当前分频器值pd_timeout(int) — 当前过程数据超时值
示例:
status = slave.watchdog_status
if status is not None and status['status'] != 0:
print(f"看门狗触发! 计数: {status['counter']}")
状态切换
set_state(state, timeout_ms=5000)
def set_state(state: EcState, timeout_ms: int = 5000) -> bool
设置单个从站 EtherCAT 状态(带超时)。用于手动恢复或将单个从站切换到指定状态,整网级状态机请使用 master.set_state()。
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
| state | EcState | — | 目标状态 |
| timeout_ms | int | 5000 | 超时时间(毫秒) |
返回值:
| 类型 | 说明 |
|---|---|
| bool | 是否成功 |
状态切换遵循 EtherCAT 标准状态机流程,协议层自动处理中间状态。例如从 INIT 切换到 OP 会自动经过 PreOp → SafeOp → OP。
示例:
# 手动恢复单个从站到 OP
if slave.state != EcState.OP:
slave.set_state(EcState.OP)
# 将从站切换到 Init(重置)
slave.set_state(EcState.INIT, timeout_ms=5000)
ESC 寄存器访问 (高级)
直接读写从站 ESC (EtherCAT Slave Controller) 寄存器,用于故障诊断、自定义 ESC 操作、底层调试。协议层走 FPRD/FPWR 数据报,自动 primary → secondary → APWR 三级回退。
正常使用 SDK 时无需调用 — 状态切换 / PDO / 邮箱等流程 SDK 已自动配置寄存器。此 API 用于深度诊断和特殊场景(例如读取错误计数器、强制端口策略、调试 ESI 烧写不生效等)。
寄存器定义见 ETG.1000.4 §6 / ETG.1000.6 §5(公开标准),例如:
| 寄存器 | 说明 |
|---|---|
| 0x0000 | Type / Revision / Build(设备类型) |
| 0x0030 | AL Control(主站发起状态请求) |
| 0x0130 | AL Status(从站当前状态) |
| 0x0134 | AL Status Code(错误码) |
| 0x0300-0x030F | 端口 0-3 错误计数器 |
| 0x0400-0x043F | 看门狗配置 / 计数 |
read_register(addr, length)
def read_register(self, addr: int, length: int) -> Optional[bytes]
读取从站 ESC 寄存器(FPRD)。
参数:
addr(int) — 寄存器地址(例如0x0130= AL Status)length(int) — 读取字节数(1 / 2 / 4 等)
返回值:
Optional[bytes]— 读取成功返回字节数据;失败(从站离线 / 超时)返回None
write_register(addr, data)
def write_register(self, addr: int, data: bytes) -> bool
写入从站 ESC 寄存器(FPWR)。
参数:
addr(int) — 寄存器地址data(bytes) — 写入数据
返回值:
bool— 成功返回True
示例:
slave = master.slaves[0]
# 读取 AL Status (0x0130, 2 字节)
data = slave.read_register(0x0130, 2)
if data:
state = int.from_bytes(data, 'little')
print(f"AL Status = 0x{state:04X} (state={state & 0x0F}, err={(state & 0x10) != 0})")
# 读取 AL Status Code (0x0134, 错误码)
code_bytes = slave.read_register(0x0134, 2)
if code_bytes:
code = int.from_bytes(code_bytes, 'little')
print(f"AL Status Code = 0x{code:04X}")
# 写 AL Control = 0x04 (请求 SafeOp)
slave.write_register(0x0030, bytes([0x04, 0x00]))
EEPROM (SII) 访问
读写从站 SII EEPROM (Slave Information Interface, ETG.1000.6 §6)。EEPROM 存储 vendor_id / product_code / revision_no / serial_no / 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)。
read_eeprom(byte_offset, byte_length)
def read_eeprom(self, byte_offset: int, byte_length: int) -> bytes
读取从站 SII EEPROM 字节区域 (按 word 循环, 内部走 SIIReadWord)。SDK 自动处理 BUSY 轮询、字对齐, 推荐应用层优先使用此高层 API。
参数:
byte_offset(int) — 起始字节偏移 (建议偶数对齐, 奇数自动按低字节对齐)byte_length(int) — 读取字节数 (建议偶数, 奇数末尾自动取低字节)
返回值:
bytes—byte_length字节数据; 失败或参数非法返回空b""
write_eeprom(byte_offset, data)
def write_eeprom(self, byte_offset: int, data: bytes) -> bool
写入从站 SII EEPROM 字节区域 (按 word 循环, 内部走 SIIWriteWord)。byte_offset 与 len(data) 都必须是偶数。
参数:
byte_offset(int) — 起始字节偏移 (必须偶数)data(bytes) — 写入字节 (长度必须偶数)
返回值:
bool— 全部 word 成功写入返回True
示例:
slave = master.slaves[0]
# 读 vendor_id (EEPROM 字节偏移 0x10, 长度 4)
data = slave.read_eeprom(0x10, 4)
if len(data) == 4:
vendor_id = int.from_bytes(data, 'little')
print(f"VendorID = 0x{vendor_id:08X}")
# 读取头部 16 字节 (含 PDIControl / StationAlias 等)
header = slave.read_eeprom(0, 16)
print(f"EEPROM 头部: {header.hex()}")
# 写 alias address (EEPROM 字节偏移 0x08)
# 必须从站处于 Init/PreOp 状态!
if slave.state == EcState.INIT:
slave.write_eeprom(0x08, bytes([0x01, 0x00])) # alias = 1
- 首选:
read_eeprom / write_eeprom(按字节, 自动字对齐) - 次选:
slave.vendor_id / product_id / serial_number等已封装属性 - 高级用法 (按需): 通过底层 SII 接口读写原始 EEPROM 字节,用于枚举 Category / 读 PDO 映射原始字节 / 烧写 alias 等场景
DL Port 端口控制
直接读写 ESC 的 DL Port Control 寄存器(0x0101),用于端口故障注入测试和冗余 / 环拓扑的手动诊断。
正常运行时无需调用。大部分用户应该通过订阅 slave_port_link_changed 事件和读取 端口错误计数器 来诊断端口状态。仅在需要主动模拟端口故障(测试冗余切换)或排查特定端口问题时使用。
ESC 有 4 个物理端口 P0 / P1 / P2 / P3,DL Port Control 寄存器的位定义如下:
| DLPORT 值 | 行为 |
|---|---|
| 0x00 | Auto — 所有端口由 ESC 自动管理(默认) |
| 0x03 | 关闭 P0 |
| 0x0C | 关闭 P1 |
| 0x30 | 关闭 P2 |
| 0xC0 | 关闭 P3 |
SDK 自动采用 primary → secondary → APWR 三级回退写入路径,即使 P0 关闭后仍能通过副网口 / 广播恢复。
write_dl_port(value)
def write_dl_port(self, value: int) -> bool
写入从站 DL Port 控制寄存器(0x0101)。
参数:
value(int) — DLPORT 值(见上表,0-255)
返回值:
bool— 成功返回True
read_dl_port()
def read_dl_port(self) -> int
读取从站 DL Port 控制寄存器的当前值。
返回值:
int— 当前 DLPORT 值(0-255);读取失败返回0
示例:
# 模拟 P1 端口故障 (测试冗余切换)
ok = slave.write_dl_port(0x0C)
print(f"关闭 P1: {'成功' if ok else '失败'}")
# 读回确认
dlport = slave.read_dl_port()
print(f"当前 DLPORT = 0x{dlport:02X}")
# 故障恢复后还原
slave.write_dl_port(0x00) # 恢复 Auto
关闭一个端口后,观察 master.events.add_slave_port_link_changed() 和 master.diagnostics.break_point 验证冗余切换是否生效。
Startup 配置
Startup 相关属性(should_write_pdo_assignment、should_write_pdo_configuration、supports_complete_access)已包含在上方属性表中。
set_config_source_eni() / set_config_source_deni()
def set_config_source_eni() -> None
def set_config_source_deni() -> None
标记从站配置来源为 ENI 或 DENI 文件。调用后 has_executed 返回 True,config_source 返回对应来源字符串。
以下方法尚未实现,将在后续版本中添加:
auto_startup() -> bool— 自动检测 ESI/MDP/SM 并生成启动参数auto_startup_from_mdp() -> bool— 从 MDP 配置生成启动参数auto_startup_from_sm() -> bool— 从 SyncManager 配置生成启动参数refresh_pdo_startup_parameters() -> int— 刷新 PDO 启动参数
StartupParameterList 方法(通过 slave.startup 访问):
add(param)— 添加启动参数add_parameter(index, sub_index, data, ...)— 添加启动参数(显式参数)remove(index, sub_index)— 移除启动参数clear()— 清除所有启动参数apply(slave, transition, write_timing)— 应用启动参数到从站
示例:
from ethercat import StartupParameter
param = StartupParameter(
index=0x1C12,
sub_index=0,
data=bytes([0]),
transition="PS",
priority=10,
)
slave.startup.add(param)
相关结构:
IP— Init → PreOp,默认 AfterTransitionPS— PreOp → SafeOp,默认 BeforeTransitionSO— SafeOp → Op,默认 BeforeTransitionOS— Op → SafeOp,默认 AfterTransitionSP— SafeOp → PreOp,默认 AfterTransitionPI— PreOp → Init,默认 BeforeTransition
Slave 子结构 (Sub-Structures)
Phase 2-D 把 EcSlave 的平面字段重新组织为多个领域子结构, 与 C 端 master.h 一一对齐, 既可作为参数传递, 也可在 from_buffer_copy() 后做整体快照。所有子结构均通过 ctypes.Structure 实现, 自然对齐 (无 _pack_)。
from ethercat.data.structures import (
SlaveIdentity, SlaveMetadata, SlaveCapabilities, SlaveRuntime,
SlaveSmFmmu, SlaveProtoMbx, SlaveTopology, SlaveDc, SlaveMailbox,
)
SlaveIdentity
class SlaveIdentity(Structure):
vendor_id: c_uint32 # 厂商 ID (eep_man)
product_id: c_uint32 # 产品 ID (eep_id)
revision: c_uint32 # 修订版本 (eep_rev)
serial: c_uint32 # 序列号 (eep_ser)
itype: c_uint16 # 接口类型 (Itype)
dtype: c_uint16 # 设备类型 (Dtype)
身份四元组 + 接口 / 设备类型 (20 字节)。slave.verify_identity(expected) 接受本结构进行身份核对。
SlaveMetadata
class SlaveMetadata(Structure):
identity: SlaveIdentity # 身份子结构
group_name: c_ubyte * 41 # 组名称 (EC_MAXNAME + 1)
device_name: c_ubyte * 41 # 设备名称 (EC_MAXNAME + 1)
sm_count: c_uint16 # SyncManager 数量
聚合身份 + 组 / 设备名 + SM 数量 (≈104 字节)。
SlaveCapabilities
class SlaveCapabilities(Structure):
is_optional: c_uint8 # 0=必须, 1=可选 (缺席不影响 WKC)
supports_frame_repeat: c_uint8 # 0=不支持, 1=支持 ETG.1500 帧重复
mailbox_side: c_uint8 # 0=auto/dual, 1=primary, 2=secondary
coe_details: c_uint8 # CoE 协议位 (CoEdetails)
foe_details: c_uint8 # FoE 协议位 (FoEdetails)
eoe_details: c_uint8 # EoE 协议位 (EoEdetails)
soe_details: c_uint8 # SoE 协议位 (SoEdetails)
Darra 扩展能力 + 各 mailbox 协议明细 (7 字节)。
SlaveRuntime
class SlaveRuntime(Structure):
ebus_current: c_int16 # E-bus 电流 (Ebuscurrent)
block_lrw: c_uint8 # >0 时禁止使用 LRW (blockLRW)
group: c_uint8 # 分组编号
is_lost: c_uint8 # 从站是否丢失 (islost)
运行时易变状态 (≈6 字节)。slave.group / slave.is_lost 等属性即派生自此。
SlaveSmFmmu
class SlaveSmFmmu(Structure):
sm_type: c_uint8 * 8 # SM 类型 (SMtype)
sm_app_length: c_uint16 * 8 # SM 应用层长度
fmmu_func: c_uint8 * 4 # FMMU 0-3 功能
fmmu_unused: c_uint8 # 第一个未使用的 FMMU 索引
SyncManager 类型 + FMMU 功能映射 (29 字节)。
SlaveProtoMbx
class SlaveProtoMbx(Structure):
in_ptr: c_void_p # 邮箱输入缓冲区指针 (C 端字段名 in)
in_full: ctypes.c_bool # 邮箱输入是否满
overrun: c_int32 # 邮箱溢出计数
每个邮箱协议 (CoE/SoE/FoE/EoE/VoE/AoE) 对应 1 个 SlaveProtoMbx (16 字节)。
C 端字段名为 in, Python 关键字冲突, 改名为 in_ptr。ABI 偏移与 C 一致, 字段名不影响 layout。
SlaveTopology
class SlaveTopology(Structure):
has_dc: c_uint8 # 是否支持 DC
phy_type: c_uint8 # 物理端口类型 (ptype)
link_count: c_uint8 # 拓扑类型 (topology)
active_ports: c_uint8 # 活动端口位图
consumed_ports: c_uint8 # 已使用端口位图
parent: c_uint16 # 父从站站地址
parent_port: c_uint8 # 父从站端口号
entry_port: c_uint8 # 入口端口号
物理拓扑信息 (10 字节)。slave.parent / slave.active_ports 等属性派生自此。
SlaveDc
class SlaveDc(Structure):
recvtime: c_int32 * 4 # 端口 A/B/C/D DC 接收时间 (ns)
propagation_delay: c_int32 # 传播延迟 (ns)
next: c_uint16 # DC 链下一个从站
prev: c_uint16 # DC 链上一个从站
# ... cycle / shift / active 等字段, 详见源码
DC 时钟相关字段 (≈40 字节)。slave.propagation_delay / slave.dc_active 等属性派生自此。
SlaveMailbox
class SlaveMailbox(Structure):
length: c_uint16 # 写邮箱长度 (mbx_l)
write_offset: c_uint16 # 写邮箱偏移 (mbx_wo)
read_length: c_uint16 # 读邮箱长度 (mbx_rl)
read_offset: c_uint16 # 读邮箱偏移 (mbx_ro)
supported_proto: c_uint16 # 支持的邮箱协议位 ECT_MBXPROT_*
cnt: c_uint8 # 邮箱链路层协议计数器
主邮箱布局信息 (12 字节)。supported_proto 与 slave.coe / slave.foe 等访问器的可用性判断一致。
SDK 内部从 native 内存做 from_buffer_copy() 快照后通过 slave.identity / slave.metadata 等属性返回字典视图, 应用层一般用字典即可; 子结构仅在需要 ABI 对齐传递 (verify_identity) 或自定义快照时显式使用。