配置
通过 master.GetConfig() 获取 MasterConfig& 引用,访问和设置主站通信配置。所有配置属性使用 C++ 属性风格重载(同名 getter/setter)。
获取配置对象
auto& config = master.GetConfig();
属性
| 类别 | 属性 | 类型 | 读写 | 说明 |
|---|---|---|---|---|
| 周期配置 | LoopCycle() | uint32_t | 读写 | PDO 交换周期(纳秒)。WDK 内核 RT 线程以此周期发送和接收 PDO 帧,最小 31.25μs |
| 网络传输 | FrameHighPriority() | bool | 读写 | 帧高优先级(默认关闭)。通过 OS 层提升帧发送优先级。Linux: SO_PRIORITY;Windows: 线程优先级提升 |
| UseUdp() | bool | 读写 | UDP 帧模式(仅 EtherCAT 网关/EAP 设备可用,标准 ESC 从站不支持)。将数据报封装在 UDP/IP 中传输 | |
| IsUdpAvailable() | bool | 只读 | UDP 模式是否可用。反映系统初始化时 UDP socket 是否创建成功 | |
| VlanId() | uint16_t | 读写 | VLAN ID(IEEE 802.1Q,0-4095,0=禁用)。仅 WDK 驱动模式下生效 | |
| VlanPriority() | uint8_t | 读写 | VLAN 优先级 PCP(0-7,7=最高)。需要 VlanId > 0 且 WDK 驱动模式 | |
| PDO 配置 | OverlappingGroups() | bool | 读写 | PDO 重叠模式(默认不启用)。LRW 帧中输入覆盖输出位置,仅适用于 TI ESC 等特殊从站 |
| PackedMode() | bool | 读写 | Packed PDO 映射模式(默认禁用)。启用后 PDO 变量按 bit 紧密排列,不强制字节对齐,适用于 bit-level IO 模块 | |
| PDOFrameLossThreshold() | uint32_t | 读写 | PDO 连续丢帧阈值(默认 3)。连续丢帧达到此值才触发回调 | |
| 互斥锁保护 | MutexProtection() | bool | 读写 | 互斥锁保护(默认启用)。启用时自动加锁确保线程安全,禁用时由用户自行管理 |
| 自适应超时 | AdaptiveTimeoutEnabled() | bool | 读写 | 自适应超时(默认启用)。自动采样网络 RTT,动态计算最优 PDO 超时值 |
| 状态转换超时 | TimeoutInitToPreOp() | int | 读写 | INIT→PREOP 超时(毫秒),默认 0。0=使用默认 3000ms |
| TimeoutPreOpToSafeOp() | int | 读写 | PREOP→SAFEOP 超时(毫秒),默认 0。0=使用默认 10000ms | |
| TimeoutSafeOpToOp() | int | 读写 | SAFEOP→OP 超时(毫秒),默认 0。0=使用默认 5000ms | |
| 看门狗 | PdiWatchdogMs() | int | 读写 | PDI 看门狗超时(毫秒),默认 0。0=使用从站默认值 |
| ProcessDataWatchdogMs() | uint32_t | 读写 | 过程数据看门狗超时(毫秒),默认 0。0=使用从站默认值 | |
| 扫描配置 | ScanRevisionMatch() | ScanRevisionMatchMode | 读写 | 扫描从站版本匹配策略(默认 IgnoreRevision) |
| 帧重复 | FrameRepeatCount() | uint8_t | 读写 | 帧重复次数(ETG.1500 5.4.3,默认 1=禁用,范围 1-3)。全局设置,仅对组内所有从站均支持的组生效 |
| DC 配置 | DriftCompensation() | bool | 读写 | DC 漂移补偿开关(默认 false) |
| 邮箱配置 | MailboxConfig() | object | 读写 | 邮箱韧性配置。当前返回 null 表示使用默认配置 |
周期配置
LoopCycle()
uint32_t LoopCycle() const;
void LoopCycle(uint32_t ns);
PDO 交换周期时间,单位:纳秒(ns)。
主站 RT 线程(WDK 内核定时器驱动)以此周期执行 PDO 帧的发送和接收。该值决定了主站与从站之间过程数据的刷新频率 ── 值越小,数据刷新越快,但对系统实时性要求也越高。WDK 驱动最低支持 31.25μs。
Windows 系统建议不低于 125,000ns(125us)。WDK 驱动完全支持 31.25us, 更小的值在 Windows 上没有意义, 应用层无法做到更高频的写入。
示例:
auto& config = master.GetConfig();
config.LoopCycle(1000000); // 1ms = 1,000,000ns
config.LoopCycle(500000); // 500us = 500,000ns
config.LoopCycle(250000); // 250us = 250,000ns
config.LoopCycle(125000); // 125us = 125,000ns(Windows 推荐最小值)
DC 漂移补偿自动完成,无需额外配置。
邮箱报文自动附带在 PDO 周期中,不占用额外帧。
网络传输
FrameHighPriority()
bool FrameHighPriority() const;
void FrameHighPriority(bool v);
通过 OS 层提升 EtherCAT 帧的发送优先级,减少排队延迟。
默认值: false(默认关闭)
- Windows — 进程/线程优先级提升
- Linux — SO_PRIORITY=6 socket 选项,内核网络栈排队优先级(需要 root 权限)
UseUdp()
bool UseUdp() const;
void UseUdp(bool v);
UDP 帧模式(ETG.1500 5.3.7)。启用后,EtherCAT 数据报不再使用原始以太网帧(EtherType 0x88A4),而是封装在 UDP/IP 数据包中传输(UDP 端口 34980)。
标准 EtherCAT 从站的 ESC(EtherCAT Slave Controller)芯片在数据链路层工作,只能识别 EtherType=0x88A4 的原始以太网帧。UDP/IP 封装的帧对这些从站不可见。
仅适用于:
- 使用支持 UDP 协议的 EtherCAT 网关或桥接设备
- 与 EtherCAT Automation Protocol(EAP)设备通信
不适用于: 直连标准 EtherCAT 从站(EK1100、EL7041、伺服驱动等)
IsUdpAvailable()
bool IsUdpAvailable() const;
系统初始化时是否成功创建了 UDP socket。只有此方法返回 true 时,才能通过 UseUdp(true) 切换到 UDP 模式。
在某些受限环境中(如缺少网络权限、防火墙阻止等),UDP socket 可能创建失败,此时 IsUdpAvailable() 返回 false,调用 UseUdp(true) 将无效。
示例:
if (config.IsUdpAvailable()) {
config.UseUdp(true); // 切换到 UDP 模式
}
VlanId()
uint16_t VlanId() const;
void VlanId(uint16_t v);
VLAN ID(IEEE 802.1Q, ETG1000_4 表9, ETG.1500 可选功能)。范围 0-4095,0 表示禁用 VLAN 标签。
设置非零值后,所有 EtherCAT 帧将插入 4 字节的 802.1Q VLAN 标签,帧头从标准的 14 字节变为 18 字节。
VLAN 配置需要在进入 SafeOp 之前设置(Build 成功后、SetState(OP) 之前)。
VLAN 标签功能仅在安装了 WDK 内核驱动时生效。WDK 内核驱动直接发送原始帧,VLAN 标签完整保留在线缆上。
VlanPriority()
uint8_t VlanPriority() const;
void VlanPriority(uint8_t v);
VLAN 优先级(PCP ── Priority Code Point, IEEE 802.1Q, ETG.1500 可选功能)。范围 0-7,7 为最高优先级。编码在 VLAN 标签的 TCI 字段高 3 位中。
需要先设置 VlanId() 为非零值,且使用 WDK 驱动模式,此属性才有意义。在支持 QoS 的交换机中,高 PCP 值的帧将优先转发。
VLAN 典型应用场景:
- IT/OT 融合网络 ── 通过 VLAN 隔离工业控制流量与办公网络流量
- TSN(时间敏感网络) ── IEEE 802.1Q 优先级标签实现 QoS 调度
- 多网段共存 ── 同一物理网络承载多个 EtherCAT 网段
示例:
// Build() 成功后设置 VLAN(需要 WDK 驱动模式)
EtherCATMaster master(dll);
master.SetNetwork("\\Device\\NPF_{...}");
master.Build();
// 在进入 SafeOp 之前配置 VLAN
auto& config = master.GetConfig();
config.VlanId(100);
config.VlanPriority(6); // 高优先级
PDO 配置
OverlappingGroups()
bool OverlappingGroups() const;
void OverlappingGroups(bool v);
PDO 重叠模式开关。启用后,每个从站的输出和输入共享同一段逻辑地址(取两者中较大的尺寸),LRW 命令发送时写入输出,返回时 ESC 用输入数据替换同一位置,从而减少帧大小。
默认值: false(默认不启用)
只能在 INIT 或 PRE_OP 状态下设置,因为内存布局在进入 SAFE_OP 时已确定。
重叠仅发生在帧的逻辑地址层面。PDO 的输出和输入映射始终指向独立的内存区域,所有 API 行为一致。
使用 TI (Texas Instruments) EtherCAT Slave Controller 的从站必须启用重叠模式,否则 LRW 命令无法正确工作。标准 Beckhoff/第三方从站请勿启用,部分从站不支持 FMMU 逻辑地址重叠会拒绝 SAFE_OP 转换。
PackedMode()
bool PackedMode() const;
void PackedMode(bool v);
Packed PDO 映射模式开关。启用后,PDO 变量按 bit 紧密排列,不强制字节对齐。
默认值: false(默认禁用,字节对齐模式)
只能在 INIT 或 PRE_OP 状态下设置,因为内存布局在进入 SAFE_OP 时已确定。
适用于 bit-level IO 模块(如 Beckhoff EL1008/EL2008 等数字 IO 终端),这些模块的 PDO 数据为单个 bit,启用 PackedMode 可以将多个 bit IO 紧密排列在连续内存中,节省 IOmap 空间。
示例:
config.PackedMode(true); // 启用 bit 紧密排列
PDOFrameLossThreshold()
uint32_t PDOFrameLossThreshold() const;
void PDOFrameLossThreshold(uint32_t v);
PDO 连续丢帧阈值,默认值为 3。
主站在每个 PDO 周期中检测帧是否正常返回。单次丢帧被视为偶发干扰仅做计数,只有连续丢帧次数达到此阈值时才触发 PDOFrameLoss 回调,避免因偶发丢帧产生过多告警。
示例:
config.PDOFrameLossThreshold(5); // 连续丢 5 帧才触发回调
PDO 配置与从站分组配合使用。每组独立的分频器和丢帧跟踪意味着高频组和低频组的丢帧互不影响。
扫描配置
ScanRevisionMatch()
ScanRevisionMatchMode ScanRevisionMatch() const;
void ScanRevisionMatch(ScanRevisionMatchMode v);
扫描从站时的版本匹配策略。控制 Build() 过程中扫描到的从站与 DENI 配置中从站的版本号匹配严格程度。
默认值: ScanRevisionMatchMode::IgnoreRevision
相关枚举:
enum class ScanRevisionMatchMode : int {
Exact = 0, // 精确匹配 VendorID + ProductID + RevisionID
CompatibleHigher = 1, // 兼容匹配: 扫描到的 RevisionID >= 配置的 RevisionID
IgnoreRevision = 2 // 忽略 RevisionID, 仅匹配 VendorID + ProductID(默认)
};
示例:
config.ScanRevisionMatch(ScanRevisionMatchMode::CompatibleHigher);
DC 配置
DriftCompensation()
bool DriftCompensation() const;
void DriftCompensation(bool v);
void DriftCompensation(bool v, int32_t thresholdNs, int32_t gain);
DC 漂移补偿开关。启用后主站周期性检测 DC 系统时间偏差并写入补偿值 (0x0920)。
默认值: false
第三个重载支持自定义参数:
thresholdNs── 漂移阈值(纳秒),默认 1000gain── 补偿增益,默认 100
也可通过 master.EnableDriftCompensation() 方法启用,该方法额外支持配置阈值和增益参数。
示例:
// 使用默认参数
config.DriftCompensation(true);
// 自定义参数
config.DriftCompensation(true, 1000, 512); // 阈值=1000ns, 增益=512
帧重复
FrameRepeatCount()
uint8_t FrameRepeatCount() const;
void FrameRepeatCount(uint8_t v);
帧重复机制(ETG.1500 5.4.3),全局设置每周期发送相同 PDO 帧的次数,自动对符合条件的组生效。
默认值: 1(禁用),范围 1-3
此属性为主站级全局设置,运行时自动按组过滤 ── 仅对组内所有从站均在 ESI 中声明 FrameRepeatSupport=1 的组执行帧重复。组资格在 IO 映射阶段自动计算:
- 组内所有从站都支持 → 该组启用帧重复
- 组内有任何一个不支持 → 该组跳过帧重复
ETG.1500 将帧重复定义为主站级能力,重复次数全局统一。由于 EtherCAT PDO 帧以 LRW 广播方式发送,同一帧内无法对个别从站区分处理,因此按组"全有或全无"是唯一合规做法。不需要为每组单独设置不同的重复次数。
此参数及每个从站的 FrameRepeatSupport 标志均已包含在 DENI 配置文件中。导出 DENI 后加载到另一台主站时,无需 ESI 文件即可正确计算每组的帧重复资格。
示例:
// 全局设置: 对所有符合条件的组,每周期发送 2 次相同 PDO 帧
config.FrameRepeatCount(2);
互斥锁保护
MutexProtection()
bool MutexProtection() const;
void MutexProtection(bool v);
互斥锁保护开关。控制 PDO 读写时是否自动加锁确保线程安全。
- 启用(默认) ── 框架自动加锁保证线程安全
- 禁用 ── 关闭自动互斥锁,由用户自行管理线程安全,减少锁竞争开销
默认值: true
禁用互斥锁保护后,用户需要自行确保 PDO 数据的线程安全。适用于对延迟有极致要求且能自行管理并发的场景。
自适应超时
AdaptiveTimeoutEnabled()
bool AdaptiveTimeoutEnabled() const;
void AdaptiveTimeoutEnabled(bool v);
自适应超时功能开关。启用后,系统自动采样网络往返时间(RTT),动态计算最优 PDO 超时值,替代固定默认超时。
默认值: true(默认启用)
- 启用(默认) ── 自动采样 RTT,动态计算超时,显著减少超时丢帧
- 关闭 ── 使用固定默认超时值
固定超时在大多数网络中远大于实际 RTT,导致偶发丢帧时等待过长,挤占后续周期时间。自适应超时通过采样实际网络延迟并留有安全余量,计算最优超时值,显著减少超时丢帧和由此引发的连锁丢帧。
状态转换超时
TimeoutInitToPreOp()
int TimeoutInitToPreOp() const;
void TimeoutInitToPreOp(int v);
INIT→PREOP 状态转换超时时间,单位:毫秒(ms)。
默认值: 0(使用系统默认 3000ms)
设置非零值可覆盖默认超时。适用于需要较长初始化时间的从站(如固件加载、EEPROM 读取较慢的设备)。
示例:
config.TimeoutInitToPreOp(5000); // 5 秒超时
TimeoutPreOpToSafeOp()
int TimeoutPreOpToSafeOp() const;
void TimeoutPreOpToSafeOp(int v);
PREOP→SAFEOP 状态转换超时时间,单位:毫秒(ms)。
默认值: 0(使用系统默认 10000ms)
此阶段包含 SM/FMMU 配置和 PDO 映射,通常耗时最长。从站数量多或 PDO 配置复杂时可能需要增大超时值。
示例:
config.TimeoutPreOpToSafeOp(15000); // 15 秒超时
TimeoutSafeOpToOp()
int TimeoutSafeOpToOp() const;
void TimeoutSafeOpToOp(int v);
SAFEOP→OP 状态转换超时时间,单位:毫秒(ms)。
默认值: 0(使用系统默认 5000ms)
示例:
config.TimeoutSafeOpToOp(8000); // 8 秒超时
- 从站数量多 ── 大型网络(>50 从站)可能需要增大 PreOp→SafeOp 超时
- 特殊从站 ── 某些伺服驱动器或安全设备初始化较慢
- 调试阶段 ── 增大超时以便观察转换过程中的问题
- 值为 0 ── 使用系统默认值,适合大多数场景
看门狗
PdiWatchdogMs()
int PdiWatchdogMs() const;
void PdiWatchdogMs(int v);
PDI(Process Data Interface)看门狗超时,单位:毫秒(ms)。
PDI 看门狗监控从站本地应用程序(微控制器固件)对 ESC 的访问。如果从站固件在指定时间内没有访问 PDI 接口,ESC 会触发看门狗错误,表示从站应用可能已崩溃。
默认值: 0(使用从站 EEPROM/ESI 中的默认值)
示例:
config.PdiWatchdogMs(100); // PDI 看门狗 100ms
PDI 看门狗与过程数据看门狗是独立的两个监控机制。PDI 看门狗监控从站内部固件,过程数据看门狗监控主站通信。
ProcessDataWatchdogMs()
uint32_t ProcessDataWatchdogMs() const;
void ProcessDataWatchdogMs(uint32_t v);
过程数据看门狗超时,单位:毫秒(ms)。
过程数据看门狗监控主站到从站的 PDO 通信。如果从站在指定时间内没有收到有效的过程数据帧(SyncManager 2/3 未被主站访问),ESC 会触发看门狗超时,从站可能自动从 OP 降级到 SafeOp。
默认值: 0(使用从站 EEPROM/ESI 中的默认值,通常为 100ms)
示例:
config.ProcessDataWatchdogMs(200); // 过程数据看门狗 200ms
过程数据看门狗超时应大于 PDO 周期(LoopCycle)的数倍,以避免正常运行时误触发。推荐值为 PDO 周期的 10-100 倍。例如 LoopCycle=1ms 时,看门狗设为 100-200ms。
IOmap 锁定
LockIOmap / UnlockIOmap
void LockIOmap();
void UnlockIOmap();
手动锁定/解锁 IOmap,用于多轴批量原子写入。当 MutexProtection(false) 时,需要手动调用此方法保证 PDO 数据的原子性。
三种线程安全模式对比:
- 自动互斥锁 —
MutexProtection(true)(默认)。通用场景,无需关心线程安全 - 手动 IOmap 锁 —
MutexProtection(false)+LockIOmap/UnlockIOmap。多轴插补,需要批量原子写入 - 无锁 —
MutexProtection(false)且不调用 Lock。单线程写入,保证无竞争
多轴联动插补时,多个从站的目标位置必须在同一 PDO 周期内同时生效。使用手动 IOmap 锁可以保证一批写入操作在一次 PDO 帧中原子提交。
示例(多轴插补批量写入):
// 关闭自动互斥锁
master.GetConfig().MutexProtection(false);
// PDO 回调中批量写入多轴位置
master.Events().ProcessDataCyclicSync = [&](uint16_t mi) {
master.LockIOmap();
// 所有写入在同一把锁内完成,保证原子性
auto* out1 = reinterpret_cast<int32_t*>(master.GetSlave(1).OutputDataPointer());
auto* out2 = reinterpret_cast<int32_t*>(master.GetSlave(2).OutputDataPointer());
auto* out3 = reinterpret_cast<int32_t*>(master.GetSlave(3).OutputDataPointer());
if (out1) *out1 = targetPos1;
if (out2) *out2 = targetPos2;
if (out3) *out3 = targetPos3;
master.UnlockIOmap();
};
完整示例
#include "ethercat.hpp"
using namespace darra;
int main() {
try {
EtherCATMaster master(dll);
master.SetNetwork("\\Device\\NPF_{...}");
master.Build();
// 获取配置对象
auto& config = master.GetConfig();
// 配置周期 125us
config.LoopCycle(125000);
// 帧高优先级
config.FrameHighPriority(true);
// 看门狗
config.ProcessDataWatchdogMs(100);
// 漂移补偿
config.DriftCompensation(true, 1000, 512);
// 切换到 OP
master.SetState(EcState::OP);
master.Start();
printf("运行中...\n");
getchar();
} catch (const ethercat::DarraException& e) {
printf("错误: %s\n", e.what());
return -1;
}
return 0;
}
超时配置最佳实践
EtherCAT 通信涉及的多种超时字段彼此独立, 对网络异常的检测灵敏度和恢复时延有直接影响. 下表汇总常用字段、典型默认值与推荐范围, 实际部署时按照网络长度 / 干扰水平 / 实时性优先级三维平衡选取.
关键字段速查:
| 字段 | 单位 | 默认 | 推荐范围 | 影响 |
|---|---|---|---|---|
| LoopCycle | ns | 1,000,000 (1ms) | 125,000 ~ 4,000,000 (125us ~ 4ms) | PDO 周期, 决定刷新率与 CPU 负载 |
| TimeoutInitToPreOp | ms | 0 (=3000) | 3000 ~ 10000 | INIT→PREOP 等待时间 (慢从站 / EEPROM 加载) |
| TimeoutPreOpToSafeOp | ms | 0 (=10000) | 10000 ~ 30000 | PREOP→SAFEOP 等待时间 (含 SM/FMMU/PDO 映射, 大网络可加大) |
| TimeoutSafeOpToOp | ms | 0 (=5000) | 5000 ~ 15000 | SAFEOP→OP 等待时间 |
| ProcessDataWatchdogMs | ms | 0 (从站默认 ≈100) | LoopCycle × 10 ~ 100 | 从站丢失主站连接后回退 SafeOp 的时间 |
| PdiWatchdogMs | ms | 0 (从站默认) | 0 ~ 200 | 从站本地固件停止访问 ESC 的检测窗口 |
何时调大 / 调小
调大 适用场景:
- 长电缆 / 跨机柜 / 跨车间 ── 物理传输延迟大, 偶发 RTT 抖动需缓冲
- 高 EMI / 焊接 / 大功率变频器附近 ── 噪声造成偶发丢帧, 重试空间需放宽
- 跨 VLAN / TSN 复合网络 ── 经过交换机会引入排队抖动
- 大网络 (>50 从站) ──
TimeoutPreOpToSafeOp必须放大, 否则 SafeOp 转换失败 - 慢从站 (FoE 大文件下载 / EEPROM 写入) ── 邮箱 / Init→PreOp 都要拉长
调小 适用场景:
- 快速故障检测优先 ── 工业紧急停车场景, 看门狗调到 5×LoopCycle, 50ms 内检测到丢帧
- 桌面短电缆 / 实验室 ── RTT 极低, 看门狗可下探到 20~50ms
- RT 严苛 (≤ 250µs 周期) ── 整体时序紧凑, 任何超时都要短
默认 / 实验室 / 工业 / 高 EMI 四档示例
auto& config = master.GetConfig();
// (1) SDK 默认 — 适合标准短电缆 + 桌面 ~ 普通车间
config.LoopCycle(1000000); // 1ms
config.TimeoutPreOpToSafeOp(0); // = 10000ms
config.ProcessDataWatchdogMs(0); // 从站默认 (~100ms)
// (2) 实验室高速 — 短线 + 严苛 RT
config.LoopCycle(250000); // 250us
config.TimeoutPreOpToSafeOp(5000);
config.ProcessDataWatchdogMs(20); // 极快检测
// (3) 工业典型 — 长电缆 + 大网络
config.LoopCycle(1000000);
config.TimeoutPreOpToSafeOp(20000); // 大网络放宽
config.ProcessDataWatchdogMs(200);
// (4) 高 EMI / 焊接现场 — 容忍偶发丢帧
config.LoopCycle(2000000); // 2ms
config.TimeoutPreOpToSafeOp(30000);
config.ProcessDataWatchdogMs(500);
config.AdaptiveTimeoutEnabled(true); // 自适应吸收抖动
- 超时太大 ── 真实故障也要等到超时才上报, 应用层告警 / 安全停机延迟变长
- 超时太小 ── 偶发抖动被误判成故障, 频繁触发
PDOFrameLoss/StateChange噪声告警 - 看门狗 < LoopCycle × 数倍 ── 正常运行也会触发, 从站反复回退 SafeOp
- 调整后建议跑 24h 通讯压力测试再上线
启用 AdaptiveTimeoutEnabled(true) (默认开) 后, SDK 自动按真实 RTT 计算 PDO 单帧超时,
无需手动收紧 LoopCycle. 上面的 watchdog / state transition 字段仍需按场景配置.