第 4 章 网络设备驱动选型与配置
导读摘要:EtherCAT 主站要与从站通信,必须通过一块以太网卡(Network Interface Card, NIC)收发帧。IgH EtherCAT Master 提供了两大类驱动方案------Generic 通用驱动和 Native 原生驱动。选对驱动,直接决定了你的系统能否达到微秒级实时性能。本章将带你深入了解每种驱动的原理、配置方法和选型策略。
4.1 Generic 通用驱动原理与使用
什么是 Generic 驱动
Generic 驱动(ec_generic)是 IgH Master 提供的"万能后备方案"。它不修改任何网卡的原始驱动代码,而是通过 Linux 内核的 Socket 接口与网卡交互。这意味着------理论上,任何以太网网卡都能用它来跑 EtherCAT。
工作原理
我们来看看它的核心机制。在模块初始化时,Generic 驱动会遍历系统中所有以太网设备,逐个向 Master 进行"offer"注册:
c
/* 摘自 devices/generic.c */
rcu_read_lock();
for_each_netdev_rcu(&init_net, netdev) {
if (netdev->type != ARPHRD_ETHER)
continue;
/* 收集网卡描述信息:名称、ifindex、MAC 地址 */
desc = kmalloc(sizeof(ec_gen_interface_desc_t), GFP_ATOMIC);
strncpy(desc->name, netdev->name, IFNAMSIZ);
desc->netdev = netdev;
desc->ifindex = netdev->ifindex;
memcpy(desc->dev_addr, netdev->dev_addr, ETH_ALEN);
list_add_tail(&desc->list, &descs);
}
rcu_read_unlock();
对于数据收发,Generic 驱动创建了一个 PF_PACKET 类型的原始套接字(Raw Socket),协议号设为 EtherCAT 专用的 0x88A4:
c
/* 摘自 devices/generic.c */
#define ETH_P_ETHERCAT 0x88A4
ret = sock_create_kern(&init_net, PF_PACKET, SOCK_RAW,
htons(ETH_P_ETHERCAT), &dev->socket);
发送时调用 kernel_sendmsg(),接收时在轮询函数中调用 kernel_recvmsg(),每次最多处理 10 帧(budget = 10)。
优缺点
Generic 驱动最大的优点是兼容性好------不需要针对特定网卡编译补丁驱动。但它的缺点也很明显:数据经过内核网络协议栈的中间层,额外的拷贝和调度开销会增大抖动(Jitter),不适合对实时性要求严苛的场景。
使用方法
Generic 驱动默认随内核模块一起编译。如果你想显式控制,可在 configure 时指定:
bash
./configure --enable-generic # 启用(默认)
./configure --disable-generic # 禁用
加载模块:
bash
modprobe ec_generic
4.2 Native 原生驱动的优势与列表
为什么需要 Native 驱动
Native 驱动是 IgH 项目对 Linux 内核原版网卡驱动做的EtherCAT 补丁版本。它直接在驱动层绕过内核网络协议栈,将 EtherCAT 帧的收发嵌入到网卡中断/轮询路径中。这样做的好处是:
- 更低延迟:省去 Socket 层的拷贝和调度
- 更小抖动:帧收发路径可控且确定
- 更高吞吐:直接操作 DMA 描述符环
所有 Native 驱动都通过统一的设备接口(Device Interface)与 Master 通信。这组 API 定义在 ecdev.h 中:
c
/* 摘自 devices/ecdev.h ------ EtherCAT 设备接口 */
ec_device_t *ecdev_offer(struct net_device *net_dev,
ec_pollfunc_t poll, struct module *module);
void ecdev_withdraw(ec_device_t *device);
int ecdev_open(ec_device_t *device);
void ecdev_close(ec_device_t *device);
void ecdev_receive(ec_device_t *device, const void *data, size_t size);
void ecdev_set_link(ec_device_t *device, uint8_t state);
uint8_t ecdev_get_link(const ec_device_t *device);
每个 Native 驱动在初始化时调用 ecdev_offer() 将网卡注册给 Master;收到帧时调用 ecdev_receive() 传递数据;链路状态变化时调用 ecdev_set_link() 通知 Master。
支持的 Native 驱动列表
根据项目构建配置(Makefile.am 和 configure.ac),IgH Master 目前支持以下 Native 驱动:
| 驱动名称 | configure 选项 | 适用网卡 | 默认状态 |
|---|---|---|---|
| e1000 | --enable-e1000 |
Intel PRO/1000 旧款 | 禁用 |
| e1000e | --enable-e1000e |
Intel PRO/1000 PCIe 系列 | 禁用 |
| igb | --enable-igb |
Intel I210/I211/I350 等 | 禁用 |
| igc | --enable-igc |
Intel I225/I226 (2.5GbE) | 禁用 |
| r8169 | --enable-r8169 |
Realtek RTL8111/8168/8169 | 禁用 |
| 8139too | --enable-8139too |
Realtek RTL8139 (百兆) | 禁用 |
| genet | --enable-genet |
Raspberry Pi 4 板载网卡 | 禁用 |
| stmmac | --enable-stmmac-pci |
Synopsys GMAC (PCI) | 禁用 |
| ccat | --enable-ccat |
Beckhoff CCAT 专用控制器 | 禁用 |
提示 :所有 Native 驱动默认都是禁用的,你需要根据自己的硬件在
configure阶段显式开启。
4.3 e1000/e1000e/igb/igc 驱动配置
Intel 网卡是工业 EtherCAT 应用中最常见的选择。IgH 项目为 Intel 的四代千兆/2.5G 网卡驱动都提供了原生补丁。
驱动与网卡对应关系
e1000 ──→ Intel PRO/1000 (PCI 总线,老设备)
e1000e ──→ Intel PRO/1000 (PCIe 总线,82574L/I217/I218/I219 等)
igb ──→ Intel I210/I211/I350 (服务器/工业级,多队列)
igc ──→ Intel I225-V/I226 (2.5 GbE,新一代桌面/嵌入式)
编译配置
以 e1000e 和 igb 为例,典型的 configure 命令如下:
bash
./configure \
--enable-e1000e \
--with-e1000e-kernel=6.1 \
--enable-igb \
--with-igb-kernel=6.1 \
--disable-generic
--with-xxx-kernel 参数指定你当前运行的内核主版本号。IgH 会自动选择对应版本的补丁源码。例如 e1000e 驱动目录下包含了从内核 3.2 到 6.12 的多版本补丁文件(netdev-6.1-ethercat.c、netdev-6.1-orig.c 等),每个版本都有 -ethercat 和 -orig 两份,方便对比差异。
编译与加载
bash
make -j$(nproc)
make modules_install
depmod -a
# 先卸载原版驱动,再加载 EtherCAT 版
rmmod e1000e
modprobe ec_e1000e
如何选择 Intel 驱动
用 lspci 确认你的网卡型号:
bash
lspci | grep -i ethernet
# 示例输出:
# 00:1f.6 Ethernet controller: Intel Corporation Ethernet Connection I219-LM
I219 系列对应 e1000e;如果看到 I210/I211/I350 则用 igb;I225/I226 则用 igc。
4.4 r8169/8139too 驱动配置
Realtek 网卡是消费级主板的标配。虽然不如 Intel 网卡在实时性方面出色,但价格低廉,在对抖动要求不那么极端的场景下依然可用。
r8169 驱动
r8169 覆盖了 Realtek 的千兆网卡系列(RTL8111/RTL8168/RTL8169),是目前桌面主板上最常见的板载千兆网卡驱动。IgH 为它提供了从内核 3.2 到 6.12 的原生补丁,高版本内核(5.10+)还包含了独立的固件加载和 PHY 配置模块。
bash
./configure \
--enable-r8169 \
--with-r8169-kernel=6.1
8139too 驱动
8139too 针对的是更老的百兆网卡 RTL8139。这类网卡已经很少见,但在一些老旧工控机上仍然存在。注意,8139too 是以独立源文件形式管理的(非子目录),补丁文件直接放在 devices/ 根目录下:
bash
./configure \
--enable-8139too \
--with-8139too-kernel=6.1
注意事项
Realtek 网卡的中断合并(Interrupt Coalescing)行为可能导致额外的延迟。在实时性要求较高的场景中,建议通过 ethtool 调整中断参数,或者优先考虑 Intel 方案。
4.5 CCAT 专用硬件驱动
什么是 CCAT
CCAT(CCAT Communication Controller)是 Beckhoff 公司专门为 EtherCAT 设计的硬件控制器,通常集成在 Beckhoff 工控 PC(如 CX 系列)中。与通用以太网卡不同,CCAT 是原生的 EtherCAT 硬件,提供了更底层的控制能力。
驱动架构
CCAT 驱动由多个功能模块组成,定义在 devices/ccat/ 目录下:
| 文件 | 功能 |
|---|---|
module.c / module.h |
主模块入口,PCI 设备注册与功能调度 |
netdev.c / netdev.h |
网络设备驱动,支持 DMA 和 EIM 两种模式 |
sram.c |
SRAM 存储访问 |
gpio.c |
GPIO 控制 |
update.c / update.h |
固件更新功能 |
从 module.c 可以看到,CCAT 驱动根据系统能力自动选择传输模式:
c
/* 摘自 devices/ccat/module.c */
static const struct ccat_driver *const drivers[] = {
#ifdef CONFIG_GENERIC_ISA_DMA
ð_dma_driver, /* DMA 模式 ------ 性能最优 */
#endif
ð_eim_driver, /* EIM 模式 ------ 无 DMA 时的回退方案 */
#ifdef CONFIG_GPIO
&gpio_driver, /* GPIO 驱动 */
#endif
&sram_driver, /* SRAM 驱动 */
};
编译与使用
bash
./configure --enable-ccat
make -j$(nproc)
make modules_install
modprobe ec_ccat
CCAT 驱动不需要指定 --with-xxx-kernel 参数,因为它是独立的硬件驱动,不依赖于内核网卡驱动代码。
4.6 驱动选型决策矩阵
面对这么多驱动选项,如何做出正确的选择?我们整理了一个决策矩阵,帮你快速定位。
决策流程图
┌──────────────────────┐
│ 你的硬件是什么网卡? │
└──────────┬───────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
┌──────────┐ ┌────────────┐ ┌────────────┐
│ Beckhoff │ │ Intel │ │ Realtek │
│ CCAT │ │ 网卡 │ │ 网卡 │
└────┬─────┘ └─────┬──────┘ └─────┬──────┘
│ │ │
▼ ▼ ▼
ec_ccat ┌─────────────┐ ┌──────────────┐
│ 查看具体型号 │ │ 千兆 or 百兆? │
└──┬──────┬───┘ └───┬──────┬───┘
│ │ │ │
┌─────┘ └────┐ 千兆│ │百兆
▼ ▼ ▼ ▼
I210/I350 I219等 r8169 8139too
I225/I226
│ │
▼ ▼
igb / igc e1000e
┌──────────────────────────────────────────┐
│ 以上都不匹配? ──→ 使用 Generic 驱动 │
└──────────────────────────────────────────┘
性能对比参考
| 维度 | Generic | Native (Intel) | Native (Realtek) | CCAT |
|---|---|---|---|---|
| 实时性 | 一般 | 优秀 | 良好 | 最优 |
| 抖动范围 | 50~200 us | 5~30 us | 20~80 us | < 10 us |
| 兼容性 | 任意网卡 | 仅 Intel | 仅 Realtek | 仅 Beckhoff |
| 配置难度 | 低 | 中 | 中 | 低 |
| 适用场景 | 开发调试 | 生产环境 | 成本敏感场景 | 高端工控 |
经验法则:开发调试阶段用 Generic 快速验证;进入生产环境后,务必切换到 Native 驱动。如果预算允许,Intel I210 + igb 驱动是工业场景的黄金组合。
常见配置组合示例
bash
# 方案一:开发调试(任意网卡)
./configure --enable-generic
# 方案二:Intel I210 生产环境
./configure --disable-generic --enable-igb --with-igb-kernel=$(uname -r | cut -d. -f1-2)
# 方案三:Intel I219 + Realtek 双网卡
./configure --enable-e1000e --with-e1000e-kernel=6.1 \
--enable-r8169 --with-r8169-kernel=6.1
# 方案四:Beckhoff 工控 PC
./configure --enable-ccat
小结
本章我们系统梳理了 IgH EtherCAT Master 的驱动体系:
- Generic 驱动通过内核 Socket 接口工作,兼容性最好,但实时性一般,适合开发调试。
- Native 驱动直接在网卡驱动层集成 EtherCAT 支持,性能远优于 Generic,是生产环境的首选。
- Intel 系列(e1000/e1000e/igb/igc)覆盖了从老款 PCI 到新款 2.5GbE 的全线产品,是工业场景的主力选择。
- Realtek 系列(r8169/8139too)适合成本敏感的场景,但实时性不如 Intel。
- CCAT 驱动是 Beckhoff 专用方案,硬件原生支持 EtherCAT,性能最优但限定硬件平台。
- 选型的核心原则是:先看硬件,再看场景,最后定驱动。
下一章预告 :第 5 章我们将深入 EtherCAT Master 的核心配置------包括主站参数调优、多主站实例管理、以及
/etc/sysconfig/ethercat配置文件的详细解读。掌握了驱动选型之后,是时候让你的主站真正跑起来了。