EC 伺服掉 OP 状态排查记录

背景

近期在客户现场发现频繁报出“伺服不在 OP 状态”的报警。客户的系统基于我们的二次开发。为了弄清楚问题来源,我们在内部环境复现并记录如下排查过程。

现象描述

  • 直接使用我们提供的标准示例程序运行,伺服能够稳定保持在 OP 状态,不出现报警。
  • 将示例程序编译成动态库后,基于该库开发的简易测试程序(无额外业务逻辑)运行正常。
  • 同一份库交付给客户后,客户的二次开发程序运行一段时间后仍然会报“伺服不在 OP”。

排查过程

  1. 确认主站 CPU 绑定情况
    默认情况下,EtherCAT 主站线程绑定在 CPU0 上。通过以下命令确认线程运行的 CPU:

    ps -eLo pid,tid,comm,psr,cls,rtprio | grep -Ei '(EtherCAT|ec_master|eoe)'
    
    taskset -p -c {pid}
    

    在客户现场与我们内部测试中,主站线程都确认为运行在 CPU0

  2. 检查客户进程 CPU 亲和性

     pgrep -fa nrc2.out
    
    taskset -p -c {pid}
    

    客户的二次开发程序名为 nrc2.out。我们同样用上述命令确认线程亲和性,发现它同样集中在 CPU0,与主站线程争用同一核心。

  3. 调整客户进程亲和性
    通过 tasksetnrc2.out 进程的 CPU 亲和性调整到 CPU1-CPU3,避免与主站线程争抢核心资源。示例命令如下:

    taskset -c 1-3 ./nrc2.out
    

    调整后,在相同场景下运行未再复现“伺服不在 OP”报警,伺服状态稳定。

结论与建议

  • 问题根因初步判断为客户程序与主站线程抢占同一 CPU 核心,导致现场实时性不足,从而触发伺服掉出 OP。
  • 建议客户在二次开发时显式设置关键进程的 CPU 亲和性,将 EtherCAT 主站与业务逻辑线程分布到不同核心,保证主站的实时调度。
  • 若后续仍有异常,可进一步排查客户程序的实时线程优先级设定,并持续监控核心实时负载情况。

p