简介:围绕 EtherCAT 总线式多轴运动控制器开发的一份技术文档,面向工业自动化、嵌入式运动控制方向的工程师与学生,用于理解实时以太网在多轴同步控制中的系统设计方法。包内仅 1 个 docx 文件,压缩包约 9KB,体量轻便,适合快速通读与方案对照。文档以 ARM+FPGA 双核架构为主线,硬件侧选用 STM32F407ZG 作为核心处理器、Altera Cyclone 系列 EP4CE10E22C 作协处理器,并采用倍福 ET1200 芯片实现从站通信,同时分析外围接口、模数转换与电源管理等电路。软件侧以 C 语言嵌入 μC/OS,开发 EtherCAT 从站驱动与指令解析,并在 Quartus 中用 Verilog HDL 实现位置控制、S 型速度规划和插补模块。文中还涉及 PCB 绘制、样机搭建与上位机调试,覆盖 EtherCAT 通信、点到点与多轴同步运动等实验验证。目前已有 144 人学习,可为相关课题选型、架构设计与实验复现提供参考。
1. 一台 32 轴的贴片机为什么要放弃 CANopen 转投 EtherCAT
在贴片机、锂电卷绕、六轴机器人这类设备里,轴数一旦超过 8 根,脉冲方向信号和 CANopen 就开始暴露同一个问题:布线随轴数线性膨胀,每个通信周期能塞进的过程数据只有几十字节,多轴之间的同步抖动轻松跑到几十微秒。EtherCAT 换了个思路——一条标准以太网线把所有从站串起来,主站每个周期只发一个帧,帧在从站 ESC 芯片里被硬件"边跑边处理"(processing on the fly),每个从站只截取属于自己的那几字节、原地改写后再让帧继续往下走。30 个从站绕一圈的帧长通常只有几百微秒量级,配上分布式时钟(DC),各轴位置锁存时刻能被对齐到亚微秒级。下面要拆的就是从协议原理、主站选型,到内核实时补丁、IgH 主站编译、从站硬件与固件,再到联调时把同步抖动量化出来的完整路径,面向做运动控制板卡和伺服驱动器的嵌入式、自动化工程师。
2. EtherCAT 通信协议原理与 FMMU:逻辑寻址怎么替掉逐站寻址
2.1 从 EtherCAT 数据帧结构理解 processing on the fly
EtherCAT 没有改写以太网的物理层,它只是在标准以太网帧里占了两个字节的 EtherType(0x88A4),后面直接跟一个或多个 EtherCAT 子报文。以太网帧头 14 字节之后是 2 字节的 EtherCAT 头,其中 11 位表示整个数据区长度、4 位表示类型(一般填 1 表示走以太网直通)。再往后就是子报文,每个子报文的头部 10 字节包含命令码、索引、4 字节地址区、2 字节数据长度和 2 字节保留位,尾部另有 2 字节工作计数器 WKC。
命令码决定了这条子报文干什么:APRD/APWR 走位置寻址,FPRD/FPWR 走节点寻址,LRD/LWR/LRW 走逻辑寻址。上电枚举阶段主站用位置寻址逐个读 ESC 寄存器,确认拓扑;配置完成后切到逻辑寻址跑周期数据。WKC 是关键的自检机制,从站每正确读写一次就自增,帧回到主站后主站比对期望值,少一个就说明某个从站掉线或映射错位,这一步比读任何状态字都直接。
| 寻址方式 | 典型命令 | 使用阶段 | 主要限制 |
|---|---|---|---|
| 位置寻址 | APRD / APWR | 上电枚举、读 ESC 寄存器 | 依赖拓扑顺序,插拔后地址漂移 |
| 节点寻址 | FPRD / FPWR | 写入站地址后再寻址 | 必须先完成站地址分配 |
| 逻辑寻址 | LRD / LWR / LRW | 周期过程数据交换 | 依赖 FMMU 与 SM 配置正确 |
2.2 FMMU 与 SM 通道:多轴过程数据怎么映射进同一帧
FMMU(Fieldbus Memory Management Unit)是每个从站 ESC 内部的一组地址翻译单元,常见实现有 8 个。每个 FMMU 保存逻辑起始地址、逻辑长度、逻辑起止位、物理起始地址、物理起始位、读写类型和使能位。主站配置好之后,从站只要看到子报文里的 32 位逻辑地址落在自己的 FMMU 窗口内,就自动把数据搬运到本地 DPRAM 的对应物理地址,全程不打扰从站 CPU。
同步管理器 SM 是另一层。SM0/SM1 走邮箱通道,负责 CoE、FoE 这类非周期通信;SM2 是从站输出过程数据(主站写、从站读),SM3 是从站输入过程数据(从站写、主站读)。多轴控制器里,每根轴的命令位置、控制字、目标速度走 SM2,实际位置、状态字、力矩反馈走 SM3,主站用一条 LRW 子报文就能把全部轴的这两段内存一起刷完。
2.3 PDO 映射与 ENI 配置的落地写法
真正决定一根轴反馈什么、下发什么的,是 PDO 映射。以常见伺服从站为例,0x1600 是接收 PDO(RxPDO,主站到从站),0x1A00 是发送 PDO(TxPDO,从站到主站),每个映射条目 4 字节:16 位索引加 8 位子索引加 8 位位长。手工写映射时最容易错的是位长和字节对齐——总位长必须是 8 的整数倍,否则从站会拒绝进入 OP 状态。
<!-- ESI/ENI 中一段典型的 RxPDO 映射,控制字 + 目标位置 + 目标速度 --> <RxPdo Sm="2"> <Index>#x1600</Index> <!-- 0x6040 控制字,16 位 --> <Entry><Index>#x6040</Index><BitLen>16</BitLen></Entry> <!-- 0x607A 目标位置,32 位,单轴增量式 --> <Entry><Index>#x607A</Index><BitLen>32</BitLen></Entry> <!-- 0x60FF 目标速度,32 位 --> <Entry><Index>#x60FF</Index><BitLen>32</BitLen></Entry> </RxPdo>这段映射的逻辑是:主站在每个周期把 10 字节数据写进 SM2 对应的物理内存,从站的 PDI 中断读到后交给伺服环路。参数上要盯三处——Sm必须与从站 EEPROM 里声明的 SM 编号一致;每个Entry的BitLen求和后要能被 8 整除;Index不能重复。改完映射要用ethercat pdos核对主站侧解析出来的结果,和从站 ESI 文件对不上时,从站会卡在 PREOP 不进 SAFEOP。
3. Linux 6.6 内核实时补丁与 IgH EtherCAT 主站编译落地
3.1 内核版本、实时补丁与网卡驱动的搭配关系
EtherCAT 主站的周期抖动,最终取决于 Linux 的调度延迟。普通内核在负载下定时器抖动可以到几百微秒,运动控制要求的主站周期常常是 250 微秒到 1 毫秒,所以必须上 PREEMPT_RT 全抢占补丁。6.6 系内核是目前实时补丁跟进较完整的长期线,可选的主站网卡驱动里,igc 对应 2.5G 网卡,适合做主站独占口,一块网卡专门跑 EtherCAT,另一块跑 SSH 和日志。
内核配置阶段有几个开关直接决定能不能做出稳定的周期:
| 配置项 | 取值 | 作用 |
|---|---|---|
| CONFIG_PREEMPT_RT | y | 全抢占,把不可抢占区降到最小 |
| CONFIG_HZ | 1000 | 提高调度时基精度,减少 tick 粒度误差 |
| CONFIG_HIGHRES_TIMERS | y | 高分辨率定时器,供主站周期延时使用 |
| CONFIG_IGC | m | 主站独占网卡驱动,编译成模块便于卸载 |
| CONFIG_CPU_ISOLATION | y | 隔离出专用核跑运动任务 |
3.2 编译安装 IgH EtherCAT Master 的完整命令
下面这套流程是现场调试时我一般会走的最小路径。补丁与内核源码包从对应发行渠道获取,注意补丁版本要和内核小版本严格对应,跨版本打补丁会大面积 reject。
# 1. 解包内核并打实时补丁,补丁文件名中的版本号必须与内核一致 tar -xf linux-6.6.tar.xz cd linux-6.6 xzcat ../patch-6.6-rt.patch.xz | patch -p1 # 2. 开启实时与主站需要的驱动 make defconfig ./scripts/config --enable PREEMPT_RT ./scripts/config --enable HIGHRES_TIMERS ./scripts/config --enable CPU_ISOLATION ./scripts/config --module IGC make -j$(nproc) && sudo make modules_install && sudo make install第一段命令的逻辑:解包、打补丁、切配置、编译安装,四步之间任何一步报错都不要继续。--enable PREEMPT_RT在 6.6 上是配置项而非补丁开关,打上 rt 补丁后它才会出现在 Kconfig 中。--module IGC让网卡编译成模块而不是编进内核,主站启动时会自己把这块网卡从内核协议栈里摘出去,模块形式更容易控制加载顺序。
# 3. 编译安装主站,注意 --disable 掉不需要的网卡驱动 tar -xjf ethercat-*.tar.bz2 cd ethercat-* ./bootstrap ./configure --prefix=/opt/etherlab \ --with-linux-dir=/usr/src/linux-6.6 \ --enable-generic \ --enable-igc \ --disable-8139too make -j$(nproc) sudo make modules_install install--prefix决定主站工具链装到哪,ethercat命令行工具会在/opt/etherlab/bin下。--enable-igc生成对应网卡的 EtherCAT 驱动模块,--disable-8139too是把用不上的旧驱动排除,减少编译时间也避免模块冲突。./bootstrap只在从源码仓库获取时需要,官方发布的源码包一般已含 configure 脚本,缺 autoreconf 工具链时会报错,装autoconf automake libtool即可。
3.3 ethercat 配置:主站绑定网卡与从站扫描
安装完成后主站配置文件一般在/etc/ethercat.conf,需要指定独占网卡的 MAC 和驱动模块。
# /etc/ethercat.conf MASTER0_DEVICE="00:1b:21:aa:bb:cc" # 主站独占口的 MAC,用 ip link 查 DEVICE_MODULES="igc" # 与 configure 时 --enable 的驱动一致改完后重启主站服务,再用命令行逐层验证。MASTER0_DEVICE填错时主站会报打不开设备,此时用ip link确认网口名称和 MAC,别直接抄文档里的示例地址。DEVICE_MODULES与内核里加载的模块不一致,主站会静默退回到 Generic 驱动,Generic 走的是标准网络协议栈,抖动大且不能保证独占。
sudo systemctl restart ethercat ethercat master # 看主站状态、链路速率、从站数量 ethercat slaves -v # 列出每个从站的状态机与 ESC 型号 ethercat pdos # 核对解析出的 PDO 映射是否与 ESI 一致ethercat slaves -v的输出里,每个从站会显示OP、SAFEOP、PREOP或INIT。整条链路全部进 OP 才算通信就绪;某个从站停在 SAFEOP 通常是输入 PDO 映射不匹配,停在 PREOP 一般是 SM 配置或邮箱参数不对,先查ethercat pdos再看 ESI 文件。
4. 从站硬件电路到多轴控制器过程数据映射的实现
4.1 EtherCAT 从站硬件电路的关键器件与布线要点
从站硬件电路的核心是 ESC(EtherCAT Slave Controller)。常见方案有两类:独立 ESC 芯片配外置 PHY,或者带 ESC 硬核的 MCU。独立方案里 ESC 通过 MII 接口接两路 PHY,PHY 再经隔离变压器和 RJ45 进出,形成两个端口——一个端口接上游、一个接下游,拓扑上串成菊花链。
| 器件 | 典型作用 | 踩坑点 |
|---|---|---|
| ESC 芯片 | 处理子报文、FMMU、SM、DC | 供电与复位时序必须按手册,复位不干净会丢端口 |
| 以太网 PHY | MII 转差分信号 | 两路 PHY 的时钟要同源,否则端口间转发会丢帧 |
| 隔离变压器 | 电气隔离与共模抑制 | 中心抽头供电电压和去耦电容位置影响误码率 |
| EEPROM | 存 ESI 与站地址配置 | I2C 上拉阻值不对会导致上电读不到配置 |
| 25MHz 晶振 | ESC 与 DC 时基 | 频偏影响 DC 同步精度,选 ±25ppm 以内的 |
布线层面,MII 侧的 TX/RX 走线要等长,差分对阻抗按 100 欧姆控制,变压器到 RJ45 之间尽量短。这些细节在低速通信用不出问题,但周期压到 250 微秒以下时,误码会直接反映成 WKC 计数丢失。
4.2 从站固件中 SM、FMMU 与 PDI 的初始化顺序
从站上电后的初始化有严格顺序,顺序错了会出现主站扫不到从站、或者能扫到但进不了 OP 的情况。我一般按下面这条链路写:
/* 从站固件上电初始化顺序,伪代码,寄存器名按所用 ESC 手册替换 */ esc_read_eeprom(&cfg); /* 1. 读 EEPROM 拿到 ESI 配置与站别名 */ esc_set_station_alias(cfg.alias); /* 2. 写入站别名,主站按别名寻址 */ sm_config(0, MBX_OUT, cfg.mbx_len); /* 3. 配邮箱 SM0/SM1,供 CoE 使用 */ sm_config(1, MBX_IN, cfg.mbx_len); sm_config(2, PDO_OUT, rx_pdo_len); /* 4. 配过程数据 SM2,主站写、从站读 */ sm_config(3, PDO_IN, tx_pdo_len); /* 5. 配过程数据 SM3,从站写、主站读 */ fmmu_map(0, LOGIC_RX, rx_pdo_len, PHYS_RX, WRITE); /* 6. FMMU 映射收发区 */ fmmu_map(1, LOGIC_TX, tx_pdo_len, PHYS_TX, READ); dc_config(cfg.dc_enable, cfg.dc_cycle); /* 7. 使能 DC,写入周期时间 */ pdi_enable_irq(SM2_EVENT); /* 8. 打开 PDI 中断,周期任务开始跑 */这段逻辑的要点在第 6 步和第 7 步之间:FMMU 必须先把逻辑地址窗口和物理内存对上,DC 配置才有意义,否则主站在 OP 状态下发的 LRW 会落在无效地址上。rx_pdo_len和tx_pdo_len必须与 ENI 里声明的字节数完全一致,差一个字节从站就进不了 OP。第 8 步的中断源要选 SM2 事件而不是普通定时器,这样从站的处理节奏天然跟主站周期对齐。
4.3 多轴控制器的周期任务与插补结构
主站侧的软件结构一般是"慢任务做规划、快任务做同步"。轨迹规划、加减速、G 代码解析放在 10 毫秒级的慢任务里,每个周期算出一组插补点;真正跑在 EtherCAT 周期上的快任务只做两件事:把插补点写进 SM2 映射区,从 SM3 读出实际位置做闭环监视。把插补放到快任务里会让周期抖动直接吃掉实时余量。
/* 主站周期任务骨架,周期 1ms,运行在隔离核上 */ while (running) { clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL); next.tv_nsec += CYCLE_NS; /* 绝对时间累加,避免漂移 */ ecrt_master_receive(master); /* 收帧,填充域数据 */ ecrt_domain_process(domain); for (int i = 0; i < AXIS_NUM; i++) { EC_WRITE_S32(rx_ptr + i * 10 + 2, interp_pos[i]); /* 写目标位置 */ axis_fb[i] = EC_READ_S32(tx_ptr + i * 12 + 2); /* 读实际位置 */ } ecrt_domain_queue(domain); ecrt_master_send(master); /* 发帧,绕一圈回来 */ }关键在于next.tv_nsec += CYCLE_NS用的是绝对时间累加,如果改用相对睡眠,每次的调度误差会累积,跑几小时后相位就漂了。ecrt_master_receive必须在ecrt_domain_process之前,ecrt_domain_queue必须在ecrt_master_send之前,这四步的顺序颠倒会读到上一周期的旧数据。EC_WRITE_S32的偏移量要与 4.2 节里 SM2 的映射字节序严格对应,字节序错了表现为轴往反方向飞或者位置跳变。
5. DC 同步抖动量化与多轴联调排错
通信建立起来只是第一步,多轴控制器的验收标准是同步精度。开 DC 之后,主站周期性下发 ARMW 子报文读回各从站系统时间,从站的本地时钟按差值微调,最终各从站时钟偏差要收敛到百纳秒量级。判断是否收敛,用ethercat dc看每个从站的偏移和漂移值,偏移持续为正或为负且不收敛,说明参考时钟选错了从站,或者某个从站的晶振频偏太大。
ethercat dc -p 3 # 查看第 3 个从站的 DC 偏移、漂移与同步窗口 ethercat reg_read -p 3 -t uint32 0x0910 # 读从站系统时间,间隔采样看变化 ethercat master -v # 确认主站工作在 DC 模式而非 FreeRunethercat dc -p 3里的偏移值稳定在 ±1 微秒以内算合格,几百纳秒更好。reg_read连续采样同一个从站的系统时间寄存器,两次采样之间的差值应该接近主站周期,差得越多说明本地时钟调节还没收敛。主站侧一定要在 ENI 或代码里把 DC 参考时钟指到拓扑第一个从站,不指定时主站会自己挑,拓扑顺序一变同步就崩。
| 现象 | 常见原因 | 定位手段 |
|---|---|---|
| 某从站停在 PREOP | SM 邮箱长度与 ESI 不符 | ethercat slaves -v看状态字,查 EEPROM 配置 |
| 某从站停在 SAFEOP | 输入 PDO 映射字节数不一致 | ethercat pdos与 ESI 逐条比对 |
| WKC 计数小于期望 | 从站掉线、线缆或变压器问题 | ethercat master看 WKC,逐段换线 |
| DC 偏移不收敛 | 参考时钟未指定或晶振频偏 | ethercat dc看漂移值,换参考从站对比 |
| 周期抖动周期性变大 | 网卡中断与运动任务抢同一核 | taskset隔离核,绑中断亲和性 |
最后补一个现场常用技巧:用ethercat graph导出拓扑,把实际链路结构和 ENI 里声明的顺序做对照,插错端口在菊花链里表现为顺序错位而不是完全不通,ethercat slaves -v里从站序号和物理位置对不上时,先怀疑这一条。
本文还有配套的精品资源,点击获取