You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迁移EtherCAT机器人程序时ecrt_master_activate函数无响应求助

问题

将基于EtherCAT系统的机器人程序迁移至另一台电脑,已安装rt kernel、Xenomai及EtherLab构建的EtherCAT主站。连接所有电机驱动器后启动通信程序,初始化主站、扫描从站步骤均正常,但调用ecrt_master_activate函数时程序陷入无限等待,无法通过ctrl+c、kill命令终止进程。通过htop查看显示进程处于等待磁盘I/O状态,添加日志排查后发现该函数未被执行(未打印函数内的日志信息)。

调用ecrt_master_activate的代码

bool ECRT_Master::Activate()     // ecrt_master_activate
{
    std::cout << "m_pmaster" << m_pMaster << std::endl;
    int check;
    check = ecrt_master_activate(m_pMaster);
    std::cout << "check" << check << std::endl;
    return check ? true : false;
}

EtherLab提供的ecrt_master_activate函数实现

int ecrt_master_activate(ec_master_t *master)
{
    printf("function inside");
    ec_ioctl_master_activate_t io;
    printf("io");
    int ret;
    printf("before ioctl");
    ret = ioctl(master->fd, EC_IOCTL_ACTIVATE, &io,20);
    printf("after ioctl");
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to activate master: %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
        return -EC_IOCTL_ERRNO(ret);
    }

    master->process_data_size = io.process_data_size;

    if (master->process_data_size) {
#ifdef USE_RTDM
        /* memory-mapping was already done in kernel. The user-space addess is
         * provided in the ioctl data.
         */
        master->process_data = io.process_data;
#else
        master->process_data = mmap(0, master->process_data_size,
                PROT_READ | PROT_WRITE, MAP_SHARED, master->fd, 0);
        if (master->process_data == MAP_FAILED) {
            fprintf(stderr, "Failed to map process data: %s\n",
                    strerror(errno));
            master->process_data = NULL;
            master->process_data_size = 0;
            return -errno;
        }
#endif

        // Access the mapped region to cause the initial page fault
        master->process_data[0] = 0x00;
    }

    return 0;
}

程序最后部分日志

Commservo pass1
CommFaultReset pass1
CommTargetCurrent pass1
CommOperationMode pass1
CommPositionSpeed pass1
CSlave.cpp [Initialize] : Slave (6) Initialize.. Status [1]
CSlave.cpp [ConfigPdos] : Slave (6) Set Slave PDO Entry..
CSlave.cpp [ConfigPdos] : Slave (6) ConfigPdos.. pSlave [0x55aa486c8f00] pSyncManager [0x55aa486cb8f0]
CSlave.cpp [Initialize] : Slave (7) Initialize..
Commservo pass1
CommFaultReset pass1
CommTargetCurrent pass1
CommOperationMode pass1
CommPositionSpeed pass1
CSlave.cpp [Initialize] : Slave (7) Initialize.. Status [1]
CSlave.cpp [ConfigPdos] : Slave (7) Set Slave PDO Entry..
CSlave.cpp [ConfigPdos] : Slave (7) ConfigPdos.. pSlave [0x55aa486c9080] pSyncManager [0x55aa486cba90]
CSlaveManager.cpp [Run] : Run Thread...
CMaster.cpp [Activate] : Activate...
m_pmaster0x55aa486c82d0
解决方案

从现象看,进程卡在ecrt_master_activate调用入口,且处于不可中断的I/O等待状态,说明问题出在用户态到内核态的调用路径上,以下是针对性排查和解决步骤:

  • 检查EtherLab内核模块加载状态
    执行lsmod | grep ec_master确认内核模块是否正常加载,若未加载,手动加载模块:modprobe ec_master;检查模块加载参数是否正确,可通过cat /sys/module/ec_master/parameters/*查看参数配置,重点确认是否启用了RTDM(对应代码中的USE_RTDM宏)。

  • 验证EtherCAT主站设备文件权限
    确认/dev/EtherCAT0(或对应设备文件)的权限,执行ls -l /dev/EtherCAT*,确保运行程序的用户有读写权限,若权限不足,执行chmod 666 /dev/EtherCAT0或添加用户到对应设备组。

  • 排查Xenomai实时环境配置
    执行xeno-test验证Xenomai核心服务是否正常运行,若测试失败,重新检查Xenomai与RT内核的编译适配性;确认程序是否正确链接Xenomai库,编译时需添加-lxenomai -lnative等链接参数,且运行时环境变量LD_LIBRARY_PATH包含Xenomai库路径。

  • 检查EtherLab内核模块与用户态库版本匹配
    内核模块和用户态库版本必须完全一致,执行ecrt_version查看用户态版本,dmesg | grep ec_master查看内核模块版本,若版本不匹配,重新编译安装整套EtherLab环境。

  • 调试内核态调用阻塞原因
    若以上步骤无效,启用内核调试:执行echo 1 > /proc/sys/kernel/printk打开内核日志输出,重新运行程序后通过dmesg -w实时查看内核日志,定位内核态中阻塞的具体位置;若内核日志显示卡在硬件初始化,检查EtherCAT网卡的驱动适配,确认网卡支持实时传输,且已禁用网卡的节能、中断合并等功能。

  • 验证PDO配置的一致性
    虽然扫描从站正常,但需确认所有从站的PDO配置与原系统完全一致,执行ecrt_slave_config_pdos后,可通过EtherLab工具ecmastercfg查看从站状态,检查PDO映射是否正确。

内容的提问来源于stack exchange,提问作者han

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 10:12:06