跳到主要内容

主站对象字典 (Master OD)

符合 ETG.1510 标准的主站对象字典,提供主站身份信息、从站配置/状态/诊断数据,供外部诊断工具和 HMI 通过标准 SDO 接口访问。

通过 master.master_od 访问。​

ETG.1510 标准

主站对象字典按照 ETG.1510 规范实现。配合邮箱网关使用,可实现远程诊断工具对主站的标准访问。

对象索引总览​

索引类别名称子索引数读写说明
0x1000设备标识Device Type0只读0x00001389(EtherCAT Master)
0x1008设备标识Manufacturer Device Name0只读"Darra EtherCAT Master"
0x1009设备标识Manufacturer Hardware Version0只读x64
0x100A设备标识Manufacturer Software Version0只读原生库版本号(major.minor.build)
0x1018设备标识Identity Object4只读主站身份信息
0x8nnn从站配置Configuration Data40只读第 n 个从站的配置数据
0x9nnn从站信息Information Data32只读第 n 个从站的检测信息
0xAnnn从站诊断Diagnosis Data19只读第 n 个从站的诊断数据
0xF002扫描Detect Modules Command3只读从站扫描状态
0xF120主站诊断Master Diag Data16只读主站诊断数据
0xF200诊断控制Diag Interface Control16读写诊断接口控制
备注

nnn = 从站编号(1-based),索引根据 master.slave_count 动态生成。例如 3 个从站时,0x8001 ~ 0x8003、0x9001 ~ 0x9003、0xA001 ~ 0xA003 均可访问。

0x1018 — 主站身份 (Identity Object)​

子索引类别名称类型值读写说明
0身份Number of Entriesint4只读固定
1身份Vendor IDint0x00001164只读ETG 分配,固定值
2身份Product Codeint0x00000001只读固定值
3身份Revision Numberint自动只读自动从原生库版本派生(高字=主版本,低字=次版本)
4身份Serial Numberint自动自增只读每个实例自动分配 0, 1, 2...,用于多主站实例区分

0x8nnn — 从站配置数据​

每个从站对应一个 0x8nnn 对象(nnn = 从站编号),包含 ENI 中配置的静态信息。

子索引类别名称类型读写说明
0结构Number of Entriesint只读固定 40
1地址Fixed Station Addressint只读站地址(当前实现返回从站索引 slave.index)
2标识Typestr预留设备类型字符串(DriveName)
3标识Namestr预留设备名称
4标识Device Typeint预留设备类型编码
5标识Vendor IDint只读厂商 ID
6标识Product Codeint只读产品代码
7标识Revision Numberint只读修订号
8标识Serial Numberint只读序列号
33邮箱Mailbox Out Sizeint预留SM0 邮箱输出大小
34邮箱Mailbox In Sizeint预留SM1 邮箱输入大小
35链路Link Statusint预留端口链路状态(低4位:端口连接,高4位:物理链路)
36链路Link Presetint预留端口链路预设(根据拓扑设置)
37链路Flagsint预留从站标志(Bit3: 热连接组成员)
38链路Port Physicsint预留端口物理类型
39邮箱Mailbox Protocolsint预留支持的邮箱协议(CoE=0x04, FoE=0x08 等)
40诊断Diag History Supportedint预留是否支持 0x10F3 诊断历史对象
实现范围

read_object 对 0x8nnn 当前只实现子索引 0、1、5–8;标注「预留」的子索引是 ETG.1510 布局占位,读取返回 None。

0x9nnn — 从站检测信息​

每个从站对应一个 0x9nnn 对象,包含运行时检测到的实际信息。

子索引类别名称类型读写说明
0结构Number of Entriesint只读固定 32
1地址Station Addressint只读站地址(当前实现返回从站索引 slave.index)
5标识Vendor IDint只读检测到的厂商 ID
6标识Product Codeint只读检测到的产品代码
7标识Revision Numberint只读检测到的修订号
8标识Serial Numberint只读检测到的序列号
32链路DL Statusint预留DL Status 寄存器(ESC 0x0110-0x0111)
实现范围

read_object 对 0x9nnn 当前只实现子索引 0、1、5–8;子索引 32 为 ETG.1510 布局占位,读取返回 None。

0xAnnn — 从站诊断数据​

每个从站对应一个 0xAnnn 对象,包含诊断数据。子索引 18 每次读取时实时取自从站 CoE 最近一次 SDO Abort Code;其余子索引为 SDK 侧诊断缓存(初始 0,计数器可经 0xF200:16 复位),当前不随从站实时刷新。

子索引类别名称类型读写说明
0结构Number of Entriesint只读固定 19
1状态AL Statusint只读当前 AL 状态
2控制AL Controlint只读AL 控制字(写入未实现,write_object 返回 False)
3状态Last AL Status Codeint只读最近一次 AL 错误码(ESC 0x0134)
4链路Link Conn. Statusint只读端口链路连接状态
5链路Link Controlint只读链路控制(DL Control 寄存器 0x0101)
6链路Fixed Addr Conn. Port 0int只读Port 0 连接的从站配置地址
7链路Fixed Addr Conn. Port 1int只读Port 1 连接的从站配置地址
8链路Fixed Addr Conn. Port 2int只读Port 2 连接的从站配置地址
9链路Fixed Addr Conn. Port 3int只读Port 3 连接的从站配置地址
10链路Frame Error Port 0int只读Port 0 帧错误计数
11链路Frame Error Port 1int只读Port 1 帧错误计数
12链路Frame Error Port 2int只读Port 2 帧错误计数
13链路Frame Error Port 3int只读Port 3 帧错误计数
14计数Cyclic WC Error Counterint只读周期性工作计数器错误
15计数Slave Not Present Counterint只读从站不在线计数
16计数Abnormal State Change Counterint只读异常状态变化计数
17链路Disable Auto Link Controlint只读自动链路控制禁用标志
18协议Last CoE/SoE Protocol Errorint只读最近一次 CoE/SoE 协议错误码(实时取自 slave.coe.last_sdo_error)
19诊断New Diag Messagesint只读是否有新诊断消息(通过 0x10F3 检测)

0xF002 — 扫描命令​

安全保护

0xF002 扫描命令禁止外部写入。运行中执行扫描可能导致配置丢失和设备异常,因此该对象为只读。 从站扫描仅在主站初始化阶段由内部逻辑执行。 更多功能请等待未来更新。

子索引类别名称类型读写说明
0结构Number of Entriesint只读固定 3
1扫描Scan Command Requestint只读扫描命令请求(禁止外部写入)
2扫描Scan Command Statusint只读1=完成无错误, 3=完成有错误, 255=执行中
3扫描Scan Command Responsebytes只读状态 + 错误码 + 检测到的从站数
实现范围

Python 侧从站扫描不经此对象,当前实现中子索引 2 恒为 1(完成无错误)、子索引 3 中的检测从站数恒为 0。

0xF120 — 主站诊断数据​

子索引类别名称类型读写说明
0结构Number of Entriesint只读固定 16
1统计Cyclic Lost Framesint只读周期帧累计丢失计数(真实计数值,不做百分比放大)
2统计Acyclic Lost Framesint只读非周期性丢帧计数(本实现固定返回 0)
3统计Cyclic Frames/Secondint只读每秒周期帧数(取自内核总线周期,拿不到真实周期时返回 0)
4统计Acyclic Frames/Secondint只读每秒非周期帧数(本实现固定返回 0)
16状态Master Stateint只读主站当前 EtherCAT 状态

0xF200 — 诊断接口控制​

子索引类别名称类型读写说明
0结构Number of Entriesint只读固定 16
16控制Reset Diag Infoint可写写入 1 复位所有从站诊断计数器(上升沿触发)

方法​

read_object()​

def read_object(self, index: int, subindex: int) -> Optional[bytes]

读取主站对象字典中指定索引的数据。

参数:

  • index (int) — 对象索引(如 0x1018、0x8001、0xA001)
  • subindex (int) — 子索引

返回值:

  • Optional[bytes] — 读取的原始数据,未知对象返回 None

示例:

import struct

vid = master.master_od.read_object(0x8001, 5)
if vid is not None:
vendor_id = struct.unpack('<I', vid)[0]
print(f"厂商ID: 0x{vendor_id:08X}")

write_object()​

def write_object(self, index: int, subindex: int, data: bytes) -> bool

写入主站对象字典。当前仅 0xF200:16(Reset Diag Info)支持写入,其余对象写入返回 False(见上方各对象表格的读写列)。

参数:

  • index (int) — 对象索引
  • subindex (int) — 子索引
  • data (bytes) — 要写入的数据

返回值:

  • bool — 写入成功返回 True

get_object_name()​

def get_object_name(self, index: int) -> str

获取对象的名称。

参数:

  • index (int) — 对象索引

返回值:

  • str — 对象名称,未知索引返回 "Unknown"

get_subindex_count()​

def get_subindex_count(self, index: int) -> int

获取对象的子索引数量。

参数:

  • index (int) — 对象索引

返回值:

  • int — 子索引数量(未知索引返回 0)

get_supported_object_indices()​

def get_supported_object_indices(self) -> List[int]

获取当前支持的所有对象索引列表(固定索引 + 按从站数量动态生成的 0x8nnn/0x9nnn/0xAnnn)。

返回值:

  • List[int] — 支持的索引列表

读写主站对象字典​

读写统一经 master.master_od:

# 读取主站对象字典
data = master.master_od.read_object(0x1018, 1)

# 写入主站对象字典 (仅部分对象可写)
ok = master.master_od.write_object(0xF200, 16, bytes([1]))

完整示例​

import struct

od = master.master_od

# 遍历所有从站的诊断数据
for i in range(1, master.slave_count + 1):
cfg_idx = 0x8000 | i
diag_idx = 0xA000 | i

# 读取从站名称
name_data = od.read_object(cfg_idx, 3)
name = name_data.decode("ascii") if name_data else "N/A"

# 读取 AL Status 和错误码
al_status = od.read_object(diag_idx, 1)
al_code = od.read_object(diag_idx, 3)

# 读取各端口帧错误计数
port_errors = []
for p in range(4):
err = od.read_object(diag_idx, 10 + p)
port_errors.append(struct.unpack('<I', err)[0] if err else 0)

al_val = struct.unpack('<H', al_status)[0] if al_status else 0
code_val = struct.unpack('<H', al_code)[0] if al_code else 0

print(f"从站{i} [{name}]: "
f"AL=0x{al_val:04X}, Code=0x{code_val:04X}, "
f"Errors={port_errors}")

# 复位所有诊断
od.write_object(0xF200, 16, bytes([1]))