IgH EtherCAT 从入门到精通:第 3 章 第一次运行 Hello EtherCAT

第 3 章 第一次运行 Hello EtherCAT

导读摘要:完成编译安装后,接下来要让 EtherCAT Master 真正跑起来。本章将带你从配置文件开始,逐步加载内核模块、启动 Master、用命令行工具探索总线,最后分别运行内核态和用户态示例程序。读完本章,你将完成从"装好了"到"跑通了"的关键一步。


3.1 配置文件 ethercat.conf 详解

EtherCAT Master 的运行参数集中在一个配置文件中:/etc/ethercat.conf。启动脚本 ethercatctl 会在启动时 source 这个文件,把其中的 Shell 变量读入内存。

核心配置项

配置文件中最重要的变量有三组:

1) MASTER0_DEVICE ------ 指定主网卡

bash 复制代码
# 方式一:使用 MAC 地址
MASTER0_DEVICE="00:00:08:44:ab:66"

# 方式二:使用网卡接口名(脚本会自动解析为 MAC)
MASTER0_DEVICE="eth0"

# 方式三:广播地址,表示接受任意网卡(仅用于快速测试)
MASTER0_DEVICE="ff:ff:ff:ff:ff:ff"

如果需要多个 Master 实例,依次设置 MASTER1_DEVICEMASTER2_DEVICE 即可。脚本会从 MASTER0 开始循环,遇到空值即停止,变量个数决定了 Master 实例数量。

2) MASTER0_BACKUP ------ 冗余备份网卡(可选)

bash 复制代码
#MASTER0_BACKUP=""

冗余模式(Cable Redundancy)下使用。如果你只有一块网卡,可以忽略此项。

3) DEVICE_MODULES ------ 网卡驱动模块

bash 复制代码
# 可选值: 8139too, e100, e1000, e1000e, r8169, generic, igb, igc 等
DEVICE_MODULES="generic"

这个变量告诉启动脚本加载哪个 EtherCAT 专用网卡驱动。generic 是通用驱动,兼容性最好,适合入门。专用驱动(如 e1000eigb)性能更优,但需要在编译时用 --enable-<driver> 开启。

4) UPDOWN_INTERFACES ------ 自动启停的网络接口

bash 复制代码
UPDOWN_INTERFACES="eth0"

使用 generic 驱动时,网卡必须在 Master 启动前处于 UP 状态,否则所有帧都会超时。将接口名填入此变量,脚本会在 start 时自动执行 ip link set dev eth0 up

最小可运行配置

对于只有一块 Intel 网卡的测试环境,最小配置如下:

bash 复制代码
MASTER0_DEVICE="eth0"
DEVICE_MODULES="generic"
UPDOWN_INTERFACES="eth0"

3.2 加载内核模块与启动 Master

IgH EtherCAT Master 的启动由 systemd 服务 + 控制脚本协同完成。下面是它们的协作流程:

复制代码
┌──────────────────────────────────────────────────────┐
│              systemd: ethercat.service               │
│                                                      │
│  ExecStart = /usr/sbin/ethercatctl start             │
│  ExecStop  = /usr/sbin/ethercatctl stop              │
└─────────────────────┬────────────────────────────────┘
                      │
                      ▼
┌──────────────────────────────────────────────────────┐
│              ethercatctl start 流程                   │
│                                                      │
│  1. source /etc/ethercat.conf                        │
│  2. ip link set dev <UPDOWN_INTERFACES> up           │
│  3. 解析 MASTER*_DEVICE → MAC 地址列表               │
│  4. modprobe ec_master main_devices=<MAC>            │
│  5. rmmod 原生驱动 (如 e1000e)                       │
│  6. modprobe ec_<DEVICE_MODULES>                     │
└──────────────────────────────────────────────────────┘

使用 systemd 启动

bash 复制代码
# 启动 Master
sudo systemctl start ethercat

# 查看状态
sudo systemctl status ethercat

# 设置开机自启
sudo systemctl enable ethercat

手动启动(调试用)

有时候我们需要绕过 systemd 直接操作,便于观察错误输出:

bash 复制代码
# 手动加载主模块,指定网卡 MAC
sudo modprobe ec_master main_devices="00:00:08:44:ab:66"

# 加载网卡驱动模块(以 generic 为例)
sudo modprobe ec_generic

# 验证模块加载
lsmod | grep ec_

成功加载后,ec_master 模块会在内核日志中打印版本信息。我们可以通过 dmesg 确认:

bash 复制代码
dmesg | grep -i ethercat
# 预期输出类似:
# EtherCAT: Master driver 1.6.x
# EtherCAT: 1 master waiting for devices.
# EtherCAT: Accepting eth0 as main device for master 0.

ec_master 加载后,它会进入 Idle 阶段(Phase),等待网卡驱动通过 ecdev_offer() 接口提供网络设备。一旦驱动加载并完成匹配,Master 即进入正常工作状态。

停止 Master

bash 复制代码
# 通过 systemd
sudo systemctl stop ethercat

# 或手动卸载
sudo rmmod ec_generic
sudo rmmod ec_master

停止顺序与启动相反:先卸载网卡驱动模块,再卸载主模块。脚本还会重新加载原生网卡驱动,恢复普通网络功能。


3.3 使用 ethercat 命令行工具探索总线

Master 启动后,我们可以用 ethercat 命令行工具与之交互。这是日常调试最常用的工具。

查看 Master 状态

bash 复制代码
ethercat master

输出示例:

复制代码
Master0
  Phase: Idle
  Active: no
  Slaves: 3
  ...

扫描从站

bash 复制代码
# 列出总线上所有从站
ethercat slaves

# 输出示例:
# 0  0:0  PREOP  +  EK1100 EtherCAT Coupler
# 1  0:1  PREOP  +  EL2004 4Ch. Dig. Output 24V
# 2  0:2  PREOP  +  EL3152 2Ch. Ana. Input 4-20mA

每行含义依次为:从站绝对位置(Absolute Position)、别名:位置、当前 AL 状态(Application Layer State)、连接标志、设备描述。

常用子命令速查

命令 说明
ethercat master 查看 Master 概要信息
ethercat slaves 列出所有从站及其状态
ethercat pdos 查看从站 PDO(Process Data Object)映射
ethercat sdos 查看从站 SDO(Service Data Object)字典
ethercat upload -p0 --type uint16 0x1018 1 读取从站 SDO 条目
ethercat xml 导出从站信息为 XML 格式
ethercat graph 输出拓扑结构(Graphviz DOT 格式)

这些命令通过 /dev/EtherCAT0 字符设备与内核 Master 通信。如果遇到权限问题,请确保当前用户在正确的用户组中,或使用 sudo


3.4 运行 mini 内核示例程序

examples/mini/mini.c 是一个内核模块(Kernel Module)形式的示例,演示了在内核态使用 EtherCAT 实时接口的完整流程。

核心流程

示例代码的 init_mini_module() 函数展示了标准的初始化步骤:

c 复制代码
// 1. 请求 Master 实例
master = ecrt_request_master(0);

// 2. 创建过程数据域(Domain)
domain1 = ecrt_master_create_domain(master);

// 3. 获取从站配置
sc_ana_in = ecrt_master_slave_config(master, AnaInSlavePos, Beckhoff_EL3152);

// 4. 配置 PDO 映射
ecrt_slave_config_pdos(sc_ana_in, EC_END, el3152_syncs);

// 5. 注册 PDO 条目
ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs);

// 6. 激活 Master
ecrt_master_activate(master);

// 7. 启动周期性任务(100 Hz 定时器)
timer_setup(&timer, cyclic_task, 0);

周期性任务 cyclic_task() 中的数据交换循环是 EtherCAT 通信的核心:

c 复制代码
// 接收数据
ecrt_master_receive(master);
ecrt_domain_process(domain1);

// 写过程数据
EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x06 : 0x09);

// 发送数据
ecrt_domain_queue(domain1);
ecrt_master_send(master);

编译与运行

bash 复制代码
# 进入示例目录
cd examples/mini

# 编译(需要已安装的内核头文件和 EtherCAT 头文件)
make

# 加载模块(确保 Master 已启动)
sudo insmod ec_mini.ko

# 观察内核日志
dmesg | tail -20

# 卸载模块
sudo rmmod ec_mini

加载成功后,dmesg 中会看到类似输出:

复制代码
ec_mini: Starting...
ec_mini: Registering domain...
ec_mini: Configuring PDOs...
ec_mini: Activating master...
ec_mini: Started.
ec_mini: 3 slave(s).
ec_mini: AL states: 0x08.
ec_mini: Link is up.

注意:mini 示例使用内核定时器(Timer),周期为 10ms(100Hz),精度有限。生产环境中通常使用 RTAI、Xenomai 或 PREEMPT_RT 内核配合更高精度的定时机制。


3.5 运行 user 用户空间示例程序

examples/user/main.c 演示了在用户空间(User Space)使用 EtherCAT 的方法。与内核态相比,用户态程序更容易开发和调试,是大多数应用的推荐起点。

与内核态的关键差异

用户态示例使用了 POSIX 实时调度机制代替内核定时器:

c 复制代码
// 设置 FIFO 实时调度策略
struct sched_param param = {};
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
sched_setscheduler(0, SCHED_FIFO, &param);

// 锁定内存,防止页面换出
mlockall(MCL_CURRENT | MCL_FUTURE);

// 使用 clock_nanosleep 实现 1ms 周期
#define PERIOD_NS (1000000)  // 1ms
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &wakeup_time, NULL);

EtherCAT API 调用方式与内核态完全一致------ecrt_request_master()ecrt_master_create_domain()ecrt_master_activate() 等函数签名和语义不变。这是 IgH Master 设计的一大优点:同一套 API,内核态和用户态通用。

编译与运行

bash 复制代码
# 编译(安装时已生成 Makefile)
cd examples/user
make

# 运行(需要 root 权限,因为要访问 /dev/EtherCAT0 和设置实时优先级)
sudo ./ec_user_example

预期输出:

复制代码
Configuring PDOs...
Activating master...
Using priority 99.
Starting RT task with dt=1000000 ns.
3 slave(s).
AL states: 0x08.
Link is up.
Domain1: WC 3.

Ctrl+C 终止程序。用户态程序退出时会自动释放 Master,Master 回到 Idle 阶段。

用户态 vs 内核态选择建议

维度 内核态 (mini) 用户态 (user)
开发难度 高,需内核编程经验 低,标准 C 编程
调试手段 printk / dmesg printf / gdb
实时性 极高(配合 RT 内核) 高(PREEMPT_RT 内核下)
稳定性风险 bug 可能导致内核崩溃 bug 只影响用户进程
推荐场景 极端实时要求 绝大多数工业应用

3.6 常见启动问题排查

初次运行时,以下问题出现频率最高。我们逐一解析。

问题 1:No network cards for EtherCAT specified

原因ethercat.confMASTER0_DEVICE 为空。

解决:填写正确的网卡 MAC 地址或接口名。

bash 复制代码
# 查看可用网卡
ip link show

问题 2:Master 一直卡在 waiting for devices

原因ec_master 已加载,但没有网卡驱动向它注册设备。

排查步骤

  1. 检查 DEVICE_MODULES 是否设置且模块已编译
  2. 确认 ec_generic(或对应驱动)已加载:lsmod | grep ec_
  3. 使用 generic 驱动时,确认网卡接口已 UP

问题 3:Master already in use!

原因:已有程序(如 mini 模块)占用了 Master。每个 Master 实例同一时间只能被一个应用请求。

解决:先卸载或终止占用程序,再运行新程序。

问题 4:Failed to enter OPERATION phase

原因:网卡驱动未正确绑定,或网线未连接。

排查

bash 复制代码
# 检查内核日志
dmesg | grep -i ethercat

# 确认物理连接
ethtool eth0 | grep "Link detected"

问题 5:权限不足,无法访问 /dev/EtherCAT0

原因:用户态程序需要对字符设备的读写权限。

解决

bash 复制代码
# 临时方案
sudo chmod 666 /dev/EtherCAT0

# 永久方案:添加 udev 规则
echo 'KERNEL=="EtherCAT[0-9]*", MODE="0666"' | \
    sudo tee /etc/udev/rules.d/99-ethercat.rules

问题 6:所有帧超时(Timeout)

原因:使用 generic 驱动时,网卡接口未激活。

解决 :在 ethercat.conf 中设置 UPDOWN_INTERFACES,或手动执行 ip link set dev eth0 up


3.7 小结

本章我们完成了 EtherCAT Master 的首次运行全流程:

  • 配置ethercat.conf 中的三个核心变量(MASTER0_DEVICEDEVICE_MODULESUPDOWN_INTERFACES)决定了 Master 的基本行为
  • 启动 :通过 systemd 服务或手动 modprobe 加载 ec_master 和网卡驱动模块
  • 探索ethercat 命令行工具可以查看 Master 状态、扫描从站、读写 SDO
  • 内核态示例 :mini 模块展示了 ecrt_request_master()ecrt_master_activate() → 周期任务的标准流程
  • 用户态示例:user 程序使用相同的 API,配合 POSIX 实时调度实现毫秒级周期控制
  • 排查:大多数启动问题源于配置遗漏或驱动未正确加载

如果你能看到 ethercat slaves 输出从站列表,并且示例程序正常打印状态信息,恭喜你------EtherCAT 总线已经跑通了。

下一章预告:第 4 章将深入讲解网络设备驱动的选型与配置,帮助你在 Generic 通用驱动和各种 Native 原生驱动之间做出正确选择,并掌握驱动的配置方法。

相关推荐
深蓝海拓2 小时前
基于QtPy (PySide6) 的PLC-HMI工程项目(七)上位机通信部分的初步建设:socket客户端
网络·笔记·python·学习·plc
2401_873479402 小时前
金融风控中IP地址查询如何识别异常登录?IP离线库提升欺诈拦截准确率的完整指南
服务器·网络·php
Proxy_ZZ02 小时前
不同VLAN之间怎么通信?从“隔墙喊话”到“路由器搭桥”
网络·智能路由器
特长腿特长2 小时前
systemd 服务配置文件,xxx.service 编辑指南,自定义我们自己的服务。
linux·网络·云原生
木心术12 小时前
Web安全攻防实战:常见漏洞分析与防御策略
网络·数据库·web安全
海特伟业2 小时前
校园IPTV电视系统:基于TCP/IP协议的新一代交互式校园IPTV电视系统的需求锚定和方案设计
网络
熬夜的咕噜猫2 小时前
LVS+Keepalived高可用群集
大数据·网络·数据库·mysql·mysql高可用
TechWayfarer2 小时前
RSAC 2026启示录:从IP归属到IP风险画像,风控系统如何防御住宅代理与AI攻击?
网络·人工智能·python·tcp/ip·ip
dddddppppp1232 小时前
arm32段+页映射 手撕mmu的行为之软件模拟
linux·服务器·网络