从站诊断
每个从站提供独立的诊断函数,可查询端口错误、冗余、DC 同步、链路质量等信息。
从站状态(GetSlaveState、GetSlaveALStatusCode)等基础属性请参考 属性与状态机。
建议通过 事件 驱动异常处理(如 SlaveStateChanged、SlaveOffline、DCSyncLost),而非轮询。
直接读取从站诊断函数适用于 UI 显示等场景。
全局通信统计、丢包率、PDO 丢帧汇总请参考 主站诊断。
功能概览
| 功能 | 函数 | 说明 |
|---|---|---|
| 通信诊断 | ReadSlavePortErrorCounters() | ESC 端口错误计数器 (RX/帧/链路) |
| 冗余诊断 | GetSlaveRedundancyActivated() | 冗余激活、主/冗余线路断路检测 |
| DC 同步 | GetSlaveSyncWindowStatus() | 同步状态、时间差 |
| 链路质量 | GetSlaveLinkQuality() | 链路质量百分比 (0-100) |
| 从站详细信息 | GetSlaveDetailedInfo() | 单从站完整快照指针 |
| 端口断线事件 | RegisterSlavePortLinkChanged | P0-P3 link 翻转事件 |
ESC 端口错误结构:
typedef struct {
uint8_t RxErrorCount[4]; /* 各端口 RX 错误计数 [Port0-3], 物理层 CRC 或编码错误 */
uint8_t InvalidFrameCount[4]; /* 各端口无效帧计数 [Port0-3], 帧格式不正确 */
uint8_t LostLinkCount[4]; /* 各端口链路丢失计数 [Port0-3], 物理连接断开次数 */
} ec_esc_port_error_stats_t;
通信诊断
BOOL ReadSlavePortErrorCounters(uint16_t master_index, uint16_t slave_index,
uint8_t* rx_error, uint8_t* invalid_frame, uint8_t* lost_link);
BOOL ResetSlavePortErrorCounters(uint16_t master_index, uint16_t slave_index);
int ReadAllSlavePortErrorCounters(uint16_t master_index);
void* GetSlavePortErrorStats(uint16_t master_index, uint16_t slave_index);
void UpdateDiagnosticsWithESCErrors(uint16_t master_index);
ReadSlavePortErrorCounters() 读取从站各端口(4 字节数组对应 P0-P3)的 RX 错误、无效帧、链路丢失计数。ResetSlavePortErrorCounters() 重置单从站,ReadAllSlavePortErrorCounters() 一次读取所有从站并返回成功数量。GetSlavePortErrorStats() 返回内部统计指针(无需释放)。
ReadSlavePortErrorCounters() 需实时读取从站,不建议高频调用(建议 ≥ 100ms 间隔)。
冗余和 DC 状态查询函数为"始终活跃",无需启用诊断模块。
示例:
uint8_t rx[4], inv[4], lost[4];
if (dll.ReadSlavePortErrorCounters(master, 1, rx, inv, lost)) {
for (int p = 0; p < 4; p++) {
if (rx[p] || inv[p] || lost[p])
printf("从站1 P%d: RX=%u Inv=%u Lost=%u\n", p, rx[p], inv[p], lost[p]);
}
}
冗余诊断
BOOL GetSlaveRedundancyActivated(uint16_t master_index, uint16_t slave_index);
BOOL GetSlavePrimaryLinkBroken(uint16_t master_index, uint16_t slave_index);
BOOL GetSlaveSecondaryLinkBroken(uint16_t master_index, uint16_t slave_index);
仅在主站启用冗余时有意义,仅检测物理断线,不含 CRC 故障。
| 函数 | 说明 |
|---|---|
| GetSlaveRedundancyActivated | 冗余被激活(从站未丢失,但网络中存在断线,冗余机制正在工作) |
| GetSlavePrimaryLinkBroken | 主线路断路(从主端口 Port0 到该从站的路径上存在断线) |
| GetSlaveSecondaryLinkBroken | 冗余线路断路(从副端口 Port1 反向到该从站的路径上存在断线) |
全局冗余状态和断线点请参考 主站诊断 - 冗余状态。
示例:
for (uint16_t s = 1; s <= slave_count; s++) {
if (!dll.GetSlaveRedundancyActivated(master, s)) continue;
printf("从站 %d: 冗余激活", s);
if (dll.GetSlavePrimaryLinkBroken(master, s)) printf(", 主线路断路");
if (dll.GetSlaveSecondaryLinkBroken(master, s)) printf(", 冗余线路断路");
printf("\n");
}
DC 同步
BOOL GetSlaveSyncWindowStatus(uint16_t master_index, uint16_t slave_index,
int* diff_ns, int* max_diff_ns, int* min_diff_ns,
BOOL* in_sync, uint32_t* out_of_sync_count);
void ResetSlaveSyncWindowStats(uint16_t master_index, uint16_t slave_index);
int16_t GetSlaveLinkQuality(uint16_t master_index, uint16_t slave_index);
GetSlaveSyncWindowStatus() 返回当前/最大/最小偏差、是否在同步窗口内(阈值由主站 SetSyncWindowThreshold() 控制)、累计失同步次数。GetSlaveLinkQuality() 返回链路质量百分比(0-100,综合 RxError + InvalidFrame + WKC 异常计算)。详见 DC 配置 与 主站诊断 - DC 同步。
完整示例
#define DYNAMIC_LOAD
#include "ethercat.h"
#include <stdio.h>
int main(void) {
dll_t dll;
LOAD_DLL(&dll, "Darra.Core.dll");
uint16_t master = dll.Initialize();
uint16_t slave_count = dll.SetNetwork(master, "\\Device\\NPF_{GUID}", "");
dll.SetStateSequence(master, EC_STATE_OPERATIONAL, 10000);
dll.Start(master);
for (uint16_t s = 1; s <= slave_count; s++) {
printf("--- 从站 %d ---\n", s);
/* 端口错误 */
uint8_t rx[4], inv[4], lost[4];
if (dll.ReadSlavePortErrorCounters(master, s, rx, inv, lost)) {
for (int p = 0; p < 4; p++)
if (rx[p] || inv[p] || lost[p])
printf(" P%d: RX=%u Inv=%u Lost=%u\n", p, rx[p], inv[p], lost[p]);
}
/* 链路质量 */
printf(" 链路质量: %d%%\n", dll.GetSlaveLinkQuality(master, s));
/* 冗余 */
if (dll.GetSlaveRedundancyActivated(master, s))
printf(" 冗余激活: 主断=%d, 副断=%d\n",
dll.GetSlavePrimaryLinkBroken(master, s),
dll.GetSlaveSecondaryLinkBroken(master, s));
/* DC 同步 */
int diff, max_d, min_d; BOOL sync; uint32_t oos;
if (dll.GetSlaveSyncWindowStatus(master, s, &diff, &max_d, &min_d, &sync, &oos))
printf(" DC: 偏差=%dns, 同步=%s, 失步=%u\n",
diff, sync ? "是" : "否", oos);
}
dll.Stop(master);
dll.Dispose(master);
UNLOAD_DLL(&dll);
return 0;
}