4. 主站协议栈与从站状态机
EtherCAT 从站上电后并不是立刻就能参与过程数据交换,它必须沿着一条严格的状态链逐级爬升:INIT → PREOP → SAFEOP → OP。这条链由从站状态机(ESM,EtherCAT State Machine)管理,主站协议栈负责发起状态切换请求并校验从站是否真正到达目标状态。联调中绝大多数“从站不通信”“PDO 无数据”“主站报 AL Status Code”问题,本质都是某一级迁移条件没有满足。理解每一级的准入条件,比记住四个状态名更重要。
四个状态各自“能做什么、不能做什么”
ESM 的设计逻辑是:越往上,通信能力越强,但对配置正确性的要求也越高。可以把它理解为一条逐级解锁的权限链。
- INIT:只有邮箱通信(Mailbox)可用,无过程数据。主站此时通过寄存器读写完成从站识别、EEPROM 读取、SM(SyncManager)通道配置。此状态下从站不参与任何周期性数据交换。
- PREOP:邮箱通信正常,主站可下发 SDO,完成 PDO 映射、DC 同步参数、从站应用层参数配置。但过程数据通道仍未激活,输入输出数据不被刷新。
- SAFEOP:过程数据通道已建立,从站可以发送输入数据(TxPDO),但输出数据(RxPDO)处于安全状态——通常输出被清零或保持默认,不驱动实际执行器。这是“只读不写”的验证阶段。
- OP:输入输出全部生效,从站按周期正常收发过程数据,执行器可被驱动。这是正常运行的最终状态。
关键点在于:SAFEOP 是 OP 的“预演”。如果输入数据在 SAFEOP 下就已经异常(例如映射长度不符、DC 不同步),那么切 OP 必然失败。因此联调时应把 SAFEOP 当作主要验证关口,而不是急着冲 OP。
状态迁移的触发条件与校验机制
状态切换由主站写从站 AL Control 寄存器(0x0120)发起,从站执行后把结果写入 AL Status(0x0130)。主站协议栈在切换后必须回读 AL Status,确认目标状态位被置位,否则判定迁移失败并读取 AL Status Code 定位原因。常见的迁移失败条件包括:
- INIT → PREOP 失败:SM 配置非法、邮箱参数不匹配、EEPROM 校验错误。
- PREOP → SAFEOP 失败:PDO 映射与 SM 长度不一致、DC 配置冲突、从站不支持请求的同步模式。
- SAFEOP → OP 失败:DC 同步未建立(SYNC0 未到达)、输入数据无效、看门狗超时、从站内部应用未就绪。
下面这张图把四个状态、各级迁移的准入条件以及失败时的定位方向放在一起,便于对照排查。
联调失败定位的实操路径
当主站报出状态切换失败时,不要盲目重试。建议按“先看 AL Status Code,再查配置,最后查同步”的顺序推进。AL Status Code 是定位的第一手证据,例如 0x0011 表示“无效请求状态”,0x0016 表示“无效邮箱配置”,0x0024 表示“无有效输入数据”,0x0030 表示“DC 同步未建立”。
以 SAFEOP → OP 失败、AL Status Code = 0x0030 为例,说明一个完整的排查过程。该代码含义是 DC 同步未建立,通常发生在从站配置了 DC 模式但主站未正确启动分布式时钟。操作上:
- 确认从站是否真的支持并启用了 DC。读取从站 ESC 的 DC 能力寄存器,或查看 ESI 文件中
<Dc>节点是否存在。 - 检查主站 DC 配置:SYNC0 周期是否与从站期望一致。例如从站要求 1 ms 周期,主站却配置为 2 ms,SYNC0 无法对齐,从站不会进入 OP。
- 检查参考时钟从站是否被正确指定。DC 需要一个参考时钟源,通常选择第一个支持 DC 的从站。若参考时钟未设置或设置错误,SYNC0 不会产生。
- 用主站诊断工具观察 DC 漂移值(System Time Difference)。正常应在微秒级,若持续增大说明同步未收敛。
再举一个 PREOP → SAFEOP 失败的典型例子:AL Status Code = 0x0016(无效邮箱配置)或 0x0018(无效 SM 配置)。这类问题多出现在从站描述文件与主站配置不一致时。例如 ESI 文件中 RxPDO 映射为 4 字节,而主站工程里手工改成了 8 字节,SM2 长度仍为 4,切换 SAFEOP 时从站校验失败。处理方法是重新导入 ESI 文件并让主站自动生成 PDO 映射,避免手工修改映射长度。
主站协议栈在状态迁移中的角色
主站协议栈不是简单发一条切换命令就完事。它需要完成:扫描从站并建立拓扑、读取每个从站的 AL Status、按顺序逐级下发状态请求、在每级切换后回读确认、失败时记录 AL Status Code 并停止后续从站的状态推进。对于多从站系统,状态迁移通常是“逐站推进”或“广播推进 + 逐站校验”两种策略。逐站推进更利于定位,广播推进更快但失败时不易判断是哪一站的问题。联调阶段建议使用逐站推进。
此外,主站协议栈还负责在 SAFEOP 阶段校验输入数据长度和有效性。如果从站声明输入 8 字节但实际只返回 4 字节,主站应在 SAFEOP 阶段就报错,而不是等到 OP 才发现。这一层校验是联调中非常关键的“提前拦截”。
联调检查要点
| 检查项 | 关注内容 | 失败表现 |
|---|---|---|
| ESI 文件一致性 | PDO 映射、SM 长度、DC 能力 | PREOP→SAFEOP 失败,0x0016/0x0018 |
| SM 通道配置 | 邮箱 SM0/SM1、过程数据 SM2/SM3 | INIT→PREOP 失败,0x0011 |
| DC 同步参数 | SYNC0 周期、参考时钟、漂移 | SAFEOP→OP 失败,0x0030 |
| 看门狗设置 | SM 看门狗时间、PDI 看门狗 | OP 下从站掉线或回退 SAFEOP |
| WKC 校验 | 工作计数器是否等于预期从站数 | OP 下数据不刷新或主站报错 |
把状态机理解成一条“逐级解锁”的权限链,把 AL Status Code 当作定位路标,把 SAFEOP 当作主要验证关口,联调时就不会在四个状态之间反复试错。下一级能不能进,取决于当前级的条件是否真正满足,而不是主站是否发出了请求。