Skip to main content

EtherCAT

介绍 K3 EtherCAT 主站功能和使用方法。

模块介绍

K3 SDK 集成 IGH EtherCAT 1.6.8 主站协议栈和定制化实时网卡驱动,提供面向高性能实时通信的 EtherCAT 主站能力,适用于运动控制、伺服驱动和工业机器人等高实时性应用场景。

功能介绍

EtherCAT 通信系统架构如上图所示,由四个部分构成:

  • 应用层: 用户应用程序,负责实现工业控制逻辑,并通过主站提供的接口与其交互。
  • EtherCAT 主站层: 负责协议处理、总线拓扑管理、从站配置以及分布式时钟同步等核心功能。
  • EtherCAT 设备驱动层: 由实时网卡驱动构成,负责 EtherCAT 数据帧的收发。
  • 硬件层: 底层网络接口及相关物理设备。

源码结构介绍

EtherCAT 相关代码位于 drivers/net/ethercat 目录下:

|-- device # EtherCAT device driver
| |-- ecdev.h
| |-- generic
| | |-- ec_generic.c # 通用 EtherCAT 网卡驱动
| | `-- Makefile
| |-- K1
| | |-- ec_k1x_emac.c # K1 芯片千兆以太网 EtherCAT 设备驱动
| | |-- ec_k1x_emac.h
| | `-- Makefile
| |-- K3 # K3 芯片千兆以太网 EtherCAT 设备驱动
| | |-- ...
| | |-- dwmac-spacemit-ethqos-ethercat.c
| | `-- ...
| |-- Kconfig
| `-- Makefile
|-- include
| |-- config.h # 全局配置项和宏定义
| |-- ecrt.h # 用户程序接口
| |-- ectty.h
| `-- globals.h # 全局变量
|-- Kconfig
|-- Makefile
`-- master # IGH EtherCAT 主站实现
|-- cdev.c # 提供EtherCAT字符设备初始化接口
|-- cdev.h
|-- coe_emerg_ring.c # 提供处理 CoE 紧急消息接口
|-- coe_emerg_ring.h
|-- datagram.c # 提供构造 ECAT 数据报接口
|-- datagram.h
|-- datagram_pair.c # 提供构造 ECAT 数据报对的接口
|-- datagram_pair.h
|-- debug.c # 提供调试接口
|-- debug.h
|-- device.c # 提供网卡设备抽象及管理设备的接口
|-- device.h
|-- domain.c # 提供 EtherCAT domain 相关接口
|-- domain.h
|-- doxygen.c
|-- eoe_request.c
|-- eoe_request.h
|-- ethernet.c # 实现EOE功能的核心文件
|-- ethernet.h
|-- flag.c
|-- flag.h
|-- fmmu_config.c # 提供构造 FMMU 配置报文接口
|-- fmmu_config.h
|-- foe.h
|-- foe_request.c # FoE 请求处理接口
|-- foe_request.h
|-- fsm_change.c # 状态切换状态机实现
|-- fsm_change.h
|-- fsm_coe.c # CoE 协议状态机实现
|-- fsm_coe.h
|-- fsm_eoe.c # EoE 协议状态机实现
|-- fsm_eoe.h
|-- fsm_foe.c # FoE 协议状态机实现
|-- fsm_foe.h
|-- fsm_master.c # 主状态机实现
|-- fsm_master.h
|-- fsm_pdo.c # PDO 读写状态机实现
|-- fsm_pdo_entry.c # PDO 条目读写状态机实现
|-- fsm_pdo_entry.h
|-- fsm_pdo.h
|-- fsm_sii.c # 从站信息接口读写状态机实现
|-- fsm_sii.h
|-- fsm_slave.c # 从状态机实现
|-- fsm_slave_config.c # 从站配置状态机实现
|-- fsm_slave_config.h
|-- fsm_slave.h
|-- fsm_slave_scan.c # 从站扫描状态机实现
|-- fsm_slave_scan.h
|-- fsm_soe.c # SoE(Servo over EtherCAT)状态机实现
|-- fsm_soe.h
|-- globals.h
|-- ioctl.c # 提供 IOCTL 接口以支持用户态交互
|-- ioctl.h
|-- Kconfig
|-- mailbox.c # ECAT 邮箱报文接口
|-- mailbox.h
|-- Makefile
|-- master.c # 主站模块核心逻辑
|-- master.h
|-- module.c # 主站模块的初始化和清理
|-- pdo.c # PDO 管理接口
|-- pdo_entry.c # PDO 条目管理接口
|-- pdo_entry.h
|-- pdo.h
|-- pdo_list.c # PDO 链表管理接口
|-- pdo_list.h
|-- reg_request.c # 从站寄存器读写请求接口
|-- reg_request.h
|-- rtdm.c # RTDM 支持
|-- rtdm_details.h
|-- rtdm.h
|-- rtdm-ioctl.c # RTDM IOCTL 接口实现
|-- rtdm_xenomai_v3.c # 支持 Xenomai v3 实时框架的接口
|-- rt_locks.h # 实时锁实现
|-- sdo.c # SDO 管理
|-- sdo_entry.c # SDO 条目管理
|-- sdo_entry.h
|-- sdo.h
|-- sdo_request.c # SDO 请求
├── sdo_request.h
├── slave.c # 从站状态管理逻辑
|-- slave_config.c # 提供从站配置接口
|-- slave_config.h
|-- slave.h
|-- soe_errors.c # 定义 SoE 协议错误码
|-- soe_request.c # SoE 请求相关接口
|-- soe_request.h
|-- sync.c # 同步管理器相关接口
|-- sync_config.c # 配置同步管理器接口
|-- sync_config.h
|-- sync.h
|-- voe_handler.c # VOE(Vendor-specific over EtherCAT)请求
|-- voe_handler.h

关键特性

特性特性说明
自动从站配置支持自动扫描并配置连接的从站设备,简化网络配置
分布式时钟同步实现小于 1 µs 精度的分布式时钟(DC)同步
多协议支持支持 CoE、SoE、FoE 等协议
高实时性能支持 500us DC 周期,满足大部分工业应用的实时性要求
多主站组合支持配置多个主站,每个主站可管理两个网络设备:主设备和备用设备

配置介绍

主要包括 Kconfig 配置DTS 配置

Kconfig 配置

  • ETHERCAT:在 K3 平台如果要启用 EtherCAT 服务,需将此选项配置为 Y
menuconfig ETHERCAT
bool "EtherCAT support"
depends on NET && NETDEVICES && ETHERNET
help
EtherCAT is an industrial real-time fieldbus protocol that runs over
Ethernet frames (Layer 2). Selecting this option enables the EtherCAT
master subsystem and the corresponding network device interfaces.
  • EC_MASTER:启用 IgH EtherCAT 主站。
  • EC_MASTER_OF:启用基于 Device Tree 的主站配置方式,若关闭则回退为通过传统模块参数传递主站配置。
  • EC_MASTER_RUN_ON_CPU:指定 EtherCAT 主站运行的 CPU 核。
  • EC_MASTER_DEBUG_LEVEL:设置主站调试信息输出级别。
config EC_MASTER
tristate "EtherCAT master (IgH)"
depends on ETHERCAT
help
Say Y or M here to build the IgH EtherCAT master driver.
The master is controlled via a character device interface.
If unsure, say N.

config EC_MASTER_OF
bool "Use Device Tree for EtherCAT master setup"
depends on OF
default y
help
Use Device Tree to provide EtherCAT master configuration,
including master instances and bound Ethernet devices.

This mode is intended for platform-integrated setups where
EtherCAT master parameters are fixed by the board description,
so runtime module parameters are not needed.

If disabled, the original upstream module-parameter based
configuration path is used instead.

config EC_MASTER_RUN_ON_CPU
int "Run EtherCAT master on CPU"
default 1
range 0 7
help
Set the CPU (0-7) on which to run the EtherCAT master.
If unsure, the default is 1.

config EC_MASTER_DEBUG_LEVEL
int "Debug level for EtherCAT master"
default 0
range 0 2
help
Set the debug level for the EtherCAT master driver.
0: No debug information.
1: Error messages.
2: Full debug information.
  • EC_GENERIC:启用通用 EtherCAT 设备驱动。
  • EC_K3_GMAC:启用 K3 平台专用 EtherCAT 设备驱动。
config EC_GENERIC
tristate "Generic EtherCAT device support"
depends on EC_MASTER
help
Generic EtherCAT device support using the standard Linux networking
stack. This is portable but may have higher latency/jitter.

config EC_K3_GMAC
tristate "Spacemit K3 GMAC EtherCAT device support"
depends on EC_MASTER && SOC_SPACEMIT_K3
select PAGE_POOL
help
EtherCAT device support for Spacemit K3 GMAC controller.

注1: 在 K3 平台上,若需使用 EtherCAT 功能,EtherCAT、EC_MASTER、EC_DEVICE、EC_K3_GMAC 是必选项。

注2: 在 K3 平台上,默认开启 EtherCAT、EC_MASTER、EC_DEVICE、EC_K3_GMAC 和 EC_MASTER_OF 选项,如无特殊需求,用户仅需在 DTS 中完成相应节点使能,即可使用 EtherCAT 功能(见下节)。

另外,为获得更好的实时性能,建议在内核配置中启用 CONFIG_PREEMPT_RT

config PREEMPT_RT
bool "Fully Preemptible Kernel (Real-Time)"
depends on EXPERT && ARCH_SUPPORTS_RT && !COMPILE_TEST
select PREEMPTION
help
This option turns the kernel into a real-time kernel by replacing
various locking primitives (spinlocks, rwlocks, etc.) with
preemptible priority-inheritance aware variants, enforcing
interrupt threading and introducing mechanisms to break up long
non-preemptible sections. This makes the kernel, except for very
low level and critical code paths (entry code, scheduler, low
level interrupt handling) fully preemptible and brings most
execution contexts under scheduler control.

Select this if you are building a kernel for systems which
require real-time guarantees.

DTS 配置

在 DTS 中,可通过 master-count 配置主站数量,并定义对应的 master 子节点,二者需保持一致。每个 master 子节点中可通过 main-devicebackup-device 分别指定主用和备用设备。 以 k3.dtsi 中的默认配置为例,默认定义了 1 个 EtherCAT 主站实例 master0,其 main-device 绑定为 eth0,当前节点状态为 disabled

ec_master: ethercat_master {
compatible = "spacemit,igh-ec-master";
master-count = <1>;
status = "disabled";

master0 {
main-device = <&eth0>;
};
};

用户若需使用 EtherCAT,最简单的方式是在方案 DTS 中直接使能 ec_master 节点,并将对应网口的 compatible 修改为spacemit,k3-ec-gmac,配置如下:

&ec_master {
status = "okay";
};

&eth0 {
compatible = "spacemit,k3-ec-gmac", "snps,dwmac-5.10a";
}

如需修改配置,可以在方案 DTS 中覆盖 ec_master 中其他属性,例如配置两个主站:master0master1master0 使用 eth1master1 使用 eth0

&ec_master {
master-count = <2>;

master0 {
main-device = <&eth1>;
};

master1 {
main-device = <&eth0>;
};
};

&eth0 {
compatible = "spacemit,k3-ec-gmac", "snps,dwmac-5.10a";
}

&eth1 {
compatible = "spacemit,k3-ec-gmac", "snps,dwmac-5.10a";
}

接口介绍

API 介绍

下面对一些常用 API 进行介绍:

  • 请求主站实例
ec_master_t *ecrt_request_master(unsigned int master_id);
  • 创建过程数据域
ec_domain_t *ecrt_master_create_domain(ec_master_t *master);
  • 激活主站
int ecrt_master_activate(ec_master_t *master);
  • 同步主站参考时钟
int ecrt_master_sync_reference_clock_to(ec_master_t *master, uint64_t ref_time);
  • 同步所有从站时钟
void ecrt_master_sync_slave_clocks(ec_master_t *master);
  • 配置从站
ec_slave_config_t *ecrt_master_slave_config(ec_master_t *master, uint16_t alias, uint16_t position, uint32_t vendor_id, uint32_t product_code);

  • 配置从站 PDO 映射
int ecrt_slave_config_pdos(ec_slave_config_t *sc, uint16_t sync_index, const ec_sync_info_t *syncs);
  • 注册 PDO 条目到指定数据域
int ecrt_slave_config_reg_pdo_entry(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, ec_domain_t *domain, unsigned int *offset);

  • 为从站配置分布式时钟
int ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate, uint32_t sync0_cycle_time, int32_t sync0_shift, uint32_t sync1_cycle_time, int32_t sync1_shift);

Debug 介绍

sysfs

可通过 /sys/class/EtherCAT/EtherCAT0 查看主站信息:

/sys/class/EtherCAT/EtherCAT0
.
|-- dev
|-- power
| |-- autosuspend_delay_ms
| |-- control
| |-- runtime_active_time
| |-- runtime_status
| `-- runtime_suspended_time
|-- subsystem -> ../../../../class/EtherCAT
`-- uevent

  • dev:提供主站设备号信息。
  • power:管理设备的电源状态。
  • subsystem:子系统链接,表明设备属于 EtherCAT 子系统。
  • uevent:主站设备号与设备名。

测试介绍

EtherCAT 主站测试步骤:

  1. 连接从站设备 至主站网口。
  2. 上电启动系统,内核自动加载 EtherCAT 主站和实时网卡设备驱动。
  3. 主站自动扫描从站,识别成功后输出日志。
  4. 主站进入 PREOP 状态,等待用户应用程序运行。

启动日志示例如下:

[ 966.525910] k1x_ec_emac cac80000.ethernet ecm0 (uninitialized): Link is Up - 100Mbps/Full - flow control off
[ 966.535906] EtherCAT 0: Link state of ecm0 changed to UP.
[ 966.552545] EtherCAT 0: 1 slave(s) responding on main device.
[ 966.558389] EtherCAT 0: Slave states on main device: INIT.
[ 966.564036] EtherCAT 0: Scanning bus.
[ 966.739197] EtherCAT 0: Bus scanning completed in 176 ms.
[ 966.745275] EtherCAT 0: Using slave 0 as DC reference clock.
[ 966.756564] EtherCAT 0: Slave states on main device: PREOP.

在测试前,为减少其他任务调度对实时性能的影响,可以通过 cgroup v2 隔离指定 CPU,并将测试程序运行在该 CPU 上。例如隔离 CPU 2:

cd /sys/fs/cgroup

echo +cpuset > cgroup.subtree_control
mkdir -p rt-cpu2
echo 2 > rt-cpu2/cpuset.cpus
echo isolated > rt-cpu2/cpuset.cpus.partition

然后将测试程序运行在该隔离 CPU 上:

bash -c '
echo $$ > /sys/fs/cgroup/rt-cpu2/cgroup.procs
exec env EC_RT_CPU=2 /path/to/test_program
'

测试用例可基于 EtherLab 官方示例 中的 examples/dc_user/main.c 进行开发,以下示例在 500us DC 通讯周期下,连接 1 个从站进行 24h 测试,输出如下:

progress: 86393/86400
period 485042 ... 517083
exec 6709 ... 39833
latency 3843 ... 21318
progress: 86394/86400
period 485042 ... 517083
exec 6709 ... 39833
latency 3843 ... 21318
progress: 86395/86400
period 485042 ... 517083
exec 6709 ... 39833
latency 3843 ... 21318
progress: 86396/86400
period 485042 ... 517083
exec 6709 ... 39833
latency 3843 ... 21318
progress: 86397/86400
period 485042 ... 517083
exec 6709 ... 39833
latency 3843 ... 21318
progress: 86398/86400
period 485042 ... 517083
exec 6709 ... 39833
latency 3843 ... 21318
progress: 86399/86400
period 485042 ... 517083
exec 6709 ... 39833
latency 3843 ... 21318
progress: 86400/86400
period 485042 ... 517083
exec 6709 ... 39833
latency 3843 ... 21318
[84309.611731] EtherCAT 0: Releasing master

注:

  • period:给出的数值是整个测试周期内通讯周期的波动范围。
  • exec:给出的数值是整个测试周期内主站周期任务执行时间的波动范围。
  • latency:给出的数值是整个测试周期内主站唤醒延迟的波动范围。

FAQ