主站对象字典 (Master OD)
符合 ETG.1510 标准的主站对象字典,提供主站身份信息、从站配置/状态/诊断数据,供外部诊断工具和 HMI 通过标准 SDO 接口访问。
通过 master.master_od() 访问。
ETG.1510 标准
主站对象字典按照 ETG.1510 规范实现,使用标准 CoE 索引约定。与从站 CoE 对象字典不同,这里是主站自身暴露的诊断对象。配合邮箱网关使用,可实现远程诊断工具对主站的标准访问。
对象索引总览
| 索引 | 名称 | 子索引数 | 读写 | 说明 |
|---|---|---|---|---|
| 0x1000 | Device Type | 0 | 只读 | 0x00001389 (EtherCAT Master) |
| 0x1008 | Device Name | 0 | 只读 | "Darra EtherCAT Master" |
| 0x1009 | Hardware Version | 0 | 只读 | x64 |
| 0x100A | Software Version | 0 | 只读 | SDK 版本号 |
| 0x1018 | Identity Object | 4 | 只读 | 主站身份信息(见下方子索引表) |
| 0x8nnn | Configuration Data | 40 | 只读 | 第 n 个从站的配置数据 |
| 0x9nnn | Information Data | 32 | 只读 | 第 n 个从站的检测信息 |
| 0xAnnn | Diagnosis Data | 19 | 部分可写 | 第 n 个从站的诊断数据 |
| 0xF002 | Detect Modules | 3 | 只读 | 从站扫描状态 |
| 0xF120 | Master Diag Data | 16 | 只读 | 主站诊断数据 |
| 0xF200 | Diag Interface Control | 16 | 可写 | 诊断接口控制 |
备注
nnn = 从站编号 (1-based),索引根据 master.slave_count() 动态生成。例如 3 个从站时,0x8001 ~ 0x8003、0x9001 ~ 0x9003、0xA001 ~ 0xA003 均可访问。
0x1018 — 主站身份 (Identity Object)
| 子索引 | 名称 | 类型 | 值 | 说明 |
|---|---|---|---|---|
| 0 | Number of Entries | u8 | 4 | 固定 |
| 1 | Vendor ID | u32 | 0x00001164 | ETG 分配,固定值 |
| 2 | Product Code | u32 | 0x00000001 | 固定值 |
| 3 | Revision Number | u32 | 自动 | 自动从 DLL 版本派生 |
| 4 | Serial Number | u32 | 自动自增 | 每个实例自动分配 0, 1, 2... |
0x8nnn — 从站配置数据
每个从站对应一个 0x8nnn 对象,包含 ENI 中配置的静态信息。
| 子索引 | 名称 | 类型 | 说明 |
|---|---|---|---|
| 0 | Number of Entries | u8 | 固定 40 |
| 1 | Fixed Station Address | u16 | 配置地址 (ConfigAddr) |
| 2 | Type | String | 设备类型字符串 |
| 3 | Name | String | 设备名称 |
| 4 | Device Type | u32 | 设备类型编码 |
| 5 | Vendor ID | u32 | 厂商 ID |
| 6 | Product Code | u32 | 产品代码 |
| 7 | Revision Number | u32 | 修订号 |
| 8 | Serial Number | u32 | 序列号 |
| 33 | Mailbox Out Size | u16 | SM0 邮箱输出大小 |
| 34 | Mailbox In Size | u16 | SM1 邮箱输入大小 |
| 35 | Link Status | u8 | 端口链路状态 |
| 36 | Link Preset | u8 | 端口链路预设 |
| 37 | Flags | u8 | 从站标志 |
| 38 | Port Physics | u16 | 端口物理类型 |
| 39 | Mailbox Protocols | u16 | 支持的邮箱协议 |
| 40 | Diag History Supported | u8 | 是否支持 0x10F3 诊断历史 |
0x9nnn — 从站检测信息
每个从站对应一个 0x9nnn 对象,包含运行时检测到的实际信息。
| 子索引 | 名称 | 类型 | 说明 |
|---|---|---|---|
| 0 | Number of Entries | u8 | 固定 32 |
| 1 | Station Address | u16 | 实际配置地址 |
| 5 | Vendor ID | u32 | 检测到的厂商 ID |
| 6 | Product Code | u32 | 检测到的产品代码 |
| 7 | Revision Number | u32 | 检测到的修订号 |
| 8 | Serial Number | u32 | 检测到的序列号 |
| 32 | DL Status | u16 | DL Status 寄存器 (ESC 0x0110) |
0xAnnn — 从站诊断数据
每个从站对应一个 0xAnnn 对象,包含实时诊断数据。每次读取时自动更新。
| 子索引 | 名称 | 类型 | 读写 | 说明 |
|---|---|---|---|---|
| 0 | Number of Entries | u8 | 只读 | 固定 19 |
| 1 | AL Status | u16 | 只读 | 当前 AL 状态 |
| 2 | AL Control | u16 | 可写 | 写入时同步到从站 |
| 3 | Last AL Status Code | u16 | 只读 | 最近一次 AL 错误码 |
| 4 | Link Conn. Status | u8 | 只读 | 端口链路连接状态 |
| 5 | Link Control | u8 | 只读 | 链路控制 |
| 6-9 | Fixed Addr Conn. Port 0-3 | u16 | 只读 | 各端口连接的从站配置地址 |
| 10-13 | Frame Error Port 0-3 | u32 | 只读 | 各端口帧错误计数 |
| 14 | Cyclic WC Error Counter | u32 | 只读 | 周期性工作计数器错误 |
| 15 | Slave Not Present Counter | u32 | 只读 | 从站不在线计数 |
| 16 | Abnormal State Change Counter | u32 | 只读 | 异常状态变化计数 |
| 17 | Disable Auto Link Control | u8 | 只读 | 自动链路控制禁用标志 |
| 18 | Last CoE/SoE Protocol Error | u32 | 只读 | 最近一次协议错误码 |
| 19 | New Diag Messages | u8 | 只读 | 是否有新诊断消息 |
0xF120 — 主站诊断数据
| 子索引 | 名称 | 类型 | 说明 |
|---|---|---|---|
| 0 | Number of Entries | u8 | 固定 16 |
| 1 | Cyclic Lost Frames | u32 | 周期性丢帧率 (百分比 x 100) |
| 2 | Acyclic Lost Frames | u32 | 非周期性丢帧率 |
| 3 | Cyclic Frames/Second | u32 | 每秒周期帧数 |
| 4 | Acyclic Frames/Second | u32 | 每秒非周期帧数 |
| 16 | Master State | u16 | 主站当前 EtherCAT 状态 |
0xF200 — 诊断接口控制
| 子索引 | 名称 | 类型 | 读写 | 说明 |
|---|---|---|---|---|
| 0 | Number of Entries | u8 | 只读 | 固定 16 |
| 16 | Reset Diag Info | u8 | 可写 | 写入 1 复位所有诊断计数器 |
方法
vendor_id() / product_code() / revision_number() / serial_number()
pub fn vendor_id(&self) -> u32
pub fn product_code(&self) -> u32
pub fn revision_number(&self) -> u32
pub fn serial_number(&self) -> u32
主站身份信息便捷访问 (对应 0x1018:01..04).
read_object()
pub fn read_object(&self, index: u16, subindex: u8) -> Option<Vec<u8>>
读取主站对象字典中指定索引的数据。
参数:
index— 对象索引(如0x1018、0x8001、0xA001)subindex— 子索引
返回值:
Option<Vec<u8>>— 读取的原始数据,未知对象返回None
write_object()
pub fn write_object(&self, index: u16, subindex: u8, data: &[u8]) -> bool
写入主站对象字典。仅部分对象支持写入(见上方各对象表格的读写列)。
参数:
index— 对象索引subindex— 子索引data— 要写入的数据
返回值:
bool— 写入成功返回true
object_name()
pub fn object_name(&self, index: u16) -> &str
获取对象的名称。未知索引返回 "Unknown"。
subindex_count()
pub fn subindex_count(&self, index: u16) -> u8
获取对象的子索引数量。
supported_object_indices()
pub fn supported_object_indices(&self) -> Vec<u16>
获取当前支持的所有对象索引列表(固定索引 + 按从站数量动态生成的 0x8nnn/0x9nnn/0xAnnn)。
完整示例
let od = master.master_od();
// 遍历所有从站的诊断数据
for i in 1..=master.slave_count() {
let cfg_idx = 0x8000 | i;
let diag_idx = 0xA000 | i;
// 读取从站名称
let name = od.read_object(cfg_idx, 3)
.map(|d| String::from_utf8_lossy(&d).to_string())
.unwrap_or_else(|| "N/A".to_string());
// 读取 AL Status 和错误码
let al_status = od.read_object(diag_idx, 1)
.map(|d| u16::from_le_bytes([d[0], d[1]]))
.unwrap_or(0);
let al_code = od.read_object(diag_idx, 3)
.map(|d| u16::from_le_bytes([d[0], d[1]]))
.unwrap_or(0);
// 读取各端口帧错误计数
let mut port_errors = [0u32; 4];
for p in 0..4u8 {
if let Some(err) = od.read_object(diag_idx, 10 + p) {
if err.len() >= 4 {
port_errors[p as usize] = u32::from_le_bytes([err[0], err[1], err[2], err[3]]);
}
}
}
println!("从站{} [{}]: AL=0x{:04X}, Code=0x{:04X}, Errors={:?}",
i, name, al_status, al_code, port_errors);
}
// 复位所有诊断
od.write_object(0xF200, 16, &[1]);
命名映射 (与其它语言 SDK)
Rust SDK 没有完全对齐 C# / Java 的某些方法名, 而是按 Rust 风格统一:
| 其它语言 | Rust 等价 |
|---|---|
get_object_dictionary_indices() | supported_object_indices() |
get_object_description(index) | object_name(index) + subindex_count(index) |
get_entry_description(index, sub) | 暂未单独暴露 — 通过 CoEInstance::read_diagnostic_meta 或 OdList::find 间接获取 |
sdo_read_ex / sdo_write_ex | 暂未提供 — 通过 CoEInstance::sdo_read / sdo_write (默认无 ex 扩展选项); 启用 complete_access 即等价 |
read_multiple_async | 暂未提供 native 异步聚合 — Rust 风格用 CoEInstance::read_multiple 同步 + tokio::task::spawn_blocking 包装异步; 或用 CoEInstance::sdo_read_blocking 数组 + JoinHandle::join() 自行并发 |
如需上述 API, 可 fork 仓库自行加 thin wrapper, 或在 CoEInstance 上手动组合现有方法。