【原创】IgH EtherCAT主站详解(十五)--EOE网络桥架与FoE固件升级
一、EoE 网络桥接
4.7 — Ethernet over EtherCAT 虚拟网络接口与桥接配置
概览
什么是 EoE?
EoE (Ethernet over EtherCAT) 是一种通过 EtherCAT 总线隧道传输标准以太网帧的协议。它允许主站与支持 EoE 的从站之间建立虚拟网络连接,使从站像普通网络设备一样收发 TCP/IP 数据。每个支持 EoE 的从站都会在 Linux 系统中创建一个虚拟网络接口 (如 eoe0),可以配置 IP 地址并加入网桥。
EoE 典型应用
从站网络管理: 远程 Telnet/SSH 到从站内部控制器
Web 服务器: 访问从站内嵌的 Web 配置界面
文件传输: 不依赖 FoE 的文件传输方式
远程调试: 通过网络调试从站固件
技术详情
EoE 数据传输架构
EoE 帧分片机制
标准以太网帧 (MTU 1500 字节) 需要通过 EtherCAT 邮箱分片传输:
| 字段 | 大小 | 说明 |
|---|---|---|
| EoE Header | 4 字节 | 包含帧类型、分片偏移、帧号、分片标志 |
| Ethernet Header | 14 字节 | 仅在第一帧中包含 |
| Payload | 可变 | 以太网帧数据(分片) |
| Last Fragment | 1 bit | 标志是否为最后一个分片 |
EoE 配置步骤流程
完整配置案例
EoE 桥接配置示例
# ===== 方法 1: 使用 ethercat 命令行工具 =====
# 1. 为从站 0 (alias=0, position=0) 创建 EoE 接口
ethercat eoe_addif 0 0
# 输出: Created EoE interface eoe0 for alias 0, position 0
# 2. 配置 IP 地址
ip addr add 192.168.1.100/24 dev eoe0
ip link set eoe0 up
# 3. 测试连通性
ping 192.168.1.200 # 从站的 IP 地址
# ===== 方法 2: 使用网桥模式 =====
# 1. 创建网桥
brctl addbr eoebr0
# 2. 添加 EoE 接口到网桥
brctl addif eoebr0 eoe0
# 3. 配置网桥 IP
ip addr add 192.168.1.100/24 dev eoebr0
ip link set eoebr0 up
# ===== 方法 3: 模块参数自动创建 =====
# 加载模块时指定 EoE 接口
insmod ec_master.ko \
main_devices=00:11:22:33:44:55 \
eoe_interfaces=eoe0:0:0,eoe1:0:1
# 格式: 接口名:主站索引:从站位置
# ===== 删除 EoE 接口 =====
ethercat eoe_delif eoe0
ifup-eoe.sh 自动桥接脚本
IgH 提供的 script/ifup-eoe.sh 可以在网络接口启动时自动将 EoE 接口加入网桥:
script/ifup-eoe.sh
# 自定义配置
BRNAME="eoebr0" # 网桥名称
INTERFACES="" # 要桥接的接口列表
# 检查接口是否在列表中
# 创建网桥(如果不存在)
brctl addbr ${BRNAME}
# 将接口加入网桥
ip link set ${IFNAME} down
ip addr flush dev ${IFNAME}
brctl addif ${BRNAME} ${IFNAME}
ip link set ${IFNAME} up
深入源码
EoE 数据结构
源文件: master/ethernet.h, master/ethernet.c
| 字段 | 类型 | 说明 |
|---|---|---|
dev |
struct net_device * |
Linux 虚拟网络设备 |
slave |
ec_slave_t * |
关联的从站 |
opened |
unsigned int |
接口是否已打开 |
tx_skb |
struct sk_buff * |
当前发送中的 SKB |
tx_queue |
struct list_head |
SKB 发送队列 |
rx_skb |
struct sk_buff * |
当前接收中的 SKB |
rx_expected_fragment |
unsigned int |
期望的下一个分片偏移 |
tx_fragment_number |
uint16_t |
发送帧序号 |
rx_frame_number |
uint16_t |
接收帧序号 |
rate_jiffies |
unsigned long |
速率统计 |
EoE 虚拟网络设备操作
ec_netdev_ops 定义了虚拟网络设备的操作函数:
| 操作 | 函数 | 说明 |
|---|---|---|
ndo_open |
ec_eoedev_open() |
打开网络接口 |
ndo_stop |
ec_eoedev_stop() |
关闭网络接口 |
ndo_start_xmit |
ec_eoedev_tx() |
发送数据包(从 Linux 网络栈接收) |
ndo_get_stats |
ec_eoedev_stats() |
获取接口统计信息 |
EoE 数据收发流程
EoE IP 设置 FSM
源文件: master/fsm_eoe.c
EoE FSM 除了数据传输,还负责设置从站的 IP 参数:
| 状态 | 行号 | 说明 |
|---|---|---|
set_ip_start |
241 | 开始设置 IP 参数 |
set_ip_request |
275 | 发送 IP 设置请求 |
set_ip_check |
335 | 检查响应帧头 |
set_ip_response |
400 | 读取完整响应 |
set_ip_response_data |
439 | 解析设置结果 |
end |
527 | 正常结束 |
error |
516 | 错误处理 |
EoE 线程
位置: master/master.c:ec_master_eoe_start() (行 2071)
EoE 处理运行在独立的内核线程 EtherCAT-EoE 中:
- 遍历所有 EoE handler
- 对每个打开的 handler:
- 处理发送队列中的 SKB(分片发送)
- 检查从站的 EoE 接收数据
- 统计传输速率
- 如果没有数据需要处理,休眠等待唤醒
性能提示: EoE 通过邮箱通信,带宽有限(取决于邮箱大小和周期)。不适合大量数据传输,主要用于配置和诊断。典型吞吐量约 1-5 Mbps。
二、固件升级 (FoE)
4.6 — File Access over EtherCAT 固件升级端到端流程
概览
什么是 FoE?
FoE (File Access over EtherCAT) 是 EtherCAT 协议中用于文件传输的协议,类似于 TFTP。它的主要用途是从站固件升级:将固件二进制文件从主站传输到从站的非易失性存储器(Flash)。FoE 通过邮箱通信进行,支持读写两种操作。
FoE 特点
简单可靠: 协议类似 TFTP,请求-确认握手模式
分块传输: 大文件分割为多个数据块逐个传输
错误重传: 传输失败时自动重试
命令行工具:ethercat foe_write/ethercat foe_read
技术详情
FoE 写入流程 (固件升级)
以下是从主站向从站写入固件文件的完整流程:
FoE 协议帧格式
| OpCode | 名称 | 方向 | 说明 |
|---|---|---|---|
| 0x01 | WRQ (Write Request) | 主站→从站 | 请求写入文件,携带 Password 和 Filename |
| 0x02 | ACK (Acknowledge) | 从站→主站 | 确认收到数据块,携带下一个 BlockNumber |
| 0x03 | DATA | 主站→从站 | 数据块,携带 BlockNumber 和文件数据 |
| 0x04 | ERROR | 从站→主站 | 错误响应,携带错误码和错误文本 |
| 0x05 | RRQ (Read Request) | 主站→从站 | 请求读取文件 |
| 0x06 | BUSY | 从站→主站 | 从站繁忙,请求等待 |
固件升级操作步骤
固件升级命令
# 1. 查看当前从站状态
ethercat slaves
# 2. 确认从站进入 BOOT 状态 (固件升级模式)
ethercat states -p 0 BOOT
# 3. 执行固件写入
ethercat foe_write -p 0 firmware.bin
# 4. 等待传输完成,重启从站
ethercat reboot -p 0
# 5. 验证固件版本
ethercat slaves -v
FoE 读取流程 (文件读取)
从从站读取文件的流程与写入相反:
- 主站发送 RRQ (Read Request),携带 Password 和 Filename
- 从站响应 DATA 帧,携带文件数据块
- 主站发送 ACK 确认,携带下一个期望的 BlockNumber
- 重复直到所有数据传输完毕
⚠ 注意事项
从站状态: 固件升级通常需要从站进入 BOOT (Bootstrap) 状态
传输中断: 如果传输中断,从站可能处于不完整固件状态,需要重新传输
密码保护: 部分 ESC 芯片的 FoE 操作需要正确的 Password
块大小: 每个数据块大小受邮箱大小限制(通常 128-512 字节)
深入源码
FoE FSM 状态函数
源文件: master/fsm_foe.c, master/fsm_foe.h
写操作 (Write) 状态转换:
状态函数清单
| 状态函数 | 行号 | 职责 |
|---|---|---|
state_wrq_sent |
525 | WRQ 发送后,等待从站 ACK/ERROR 响应 |
state_rrq_sent |
684 | RRQ 发送后,等待从站 DATA/ERROR 响应 |
state_ack_check |
329 | 检查 ACK 帧头,发起读取完整 ACK |
state_ack_read |
392 | 读取完整 ACK 响应数据 |
state_ack_read_data |
430 | 解析 ACK 内容,获取 BlockNumber |
state_data_sent |
572 | Data 帧发送后,等待 ACK 确认 |
state_data_check |
— | 检查 Data 帧(读操作) |
state_data_read |
— | 读取 Data 帧数据(读操作) |
state_data_read_data |
— | 处理 Data 帧内容(读操作) |
state_sent_ack |
— | ACK 发送后(读操作) |
ethercat foe_write 命令实现
源文件: tool/CommandFoeWrite.cpp
命令执行流程:
- 解析命令行参数(从站位置、文件名、密码)
- 打开固件文件,读取全部内容到内存
- 创建
ec_foe_request_t,设置文件名、密码、数据 - 通过 ioctl 发送
EC_IOCTL_FOE_WRITE命令 - 内核侧创建 FoE 请求,加入从站请求队列
- Slave FSM 在其循环中检测到 FoE 请求,启动 FoE FSM
- FoE FSM 执行完整的写入握手流程
- 完成后通过 ioctl 返回结果给用户空间
FoE 错误码
| 错误码 | 名称 | 含义 |
|---|---|---|
| 0x0001 | NOT_DEFINED | 未定义错误 |
| 0x0002 | NOT_FOUND | 文件未找到 |
| 0x0003 | ACCESS_DENIED | 访问被拒绝(密码错误) |
| 0x0004 | DISK_FULL | 磁盘空间不足 |
| 0x0005 | ILLEGAL_PACKET | 非法数据包 |
| 0x0006 | PACKET_NUMBER | 包序号错误 |
| 0x0007 | OPERATION | 操作不支持 |
| 0x0008 | UNKNOWN | 未知错误 |

浙公网安备 33010602011771号