这是 "深入 FSoE" 系列文章的第五篇。在上一篇文章中,我们逐字节拆解了 FSoE 安全 PDU 的帧格式——Command、SafeData、CRC 和 ConnID 分别承载了什么安全机制。但这些字段如何协同工作、在什么时机被赋值?答案就藏在 FSoE 通信状态机之中。本文将深入分析 FSoE 的五个通信状态,逐一说明每个状态中 Master 和 Slave 在做什么,以及为什么会这样设计。
在工业通信协议中,状态机承担着"协调者"的角色——它规定了设备在什么条件下可以发送什么数据、如何响应不同类型的报文、以及异常情况下的行为准则。对于功能安全协议来说,状态机的设计还多了一层额外的约束:在任何状态下、面对任何异常,系统都必须能够可靠地进入安全状态。
FSoE 的通信状态机由 ETG.5100 规范严格定义,无论 Master 还是 Slave,都必须实现完全相同的一组状态和转换规则。TUV 等公告机构在进行协议栈认证时,状态机实现的正确性是重点审查内容之一——一个状态转换的逻辑漏洞可能导致安全功能在特定场景下失效。
FSoE 定义了五个通信状态:Reset、Session、Connection、Parameter 和 Data。这五个状态构成了一条从"完全不可信"到"建立安全通信"的渐进式握手路径。

图1 FSoE Slave 状态机
▲ ETG.5100 Figure 8 – FSoE Slave 状态机。五个状态(Reset → Session → Connection → Parameter → Data)构成一条严格的渐进式握手路径,Master 状态机与之高度对称。
前四个状态中,安全输出始终处于安全值(Fail-Safe Data = 0)。只有当状态机成功推进到 Data 状态后,安全输出才被允许激活。这一设计保证了安全功能永远不会在通信未建立的情况下被误激活。
ETG.5100 规范不仅定义了每个状态的含义,还以精确的状态表(State Table)形式规定了每个状态下的所有可能事件、转换条件和相应的动作。下面我们逐一深入每个状态。
Reset 是上电后的初始状态,也是任何通信错误发生后系统回归的"安全原点"。
进入 Reset 状态时,Master 和 Slave 执行完全相同的初始化动作:清零所有 CRC 历史值(LastCrc = 0, OldMasterCrc = 0, OldSlaveCrc = 0)、重置序列号计数器(MasterSeqNo = 1, SlaveSeqNo = 1)、安全数据初始化为全零(Fail-Safe Data)、以及通信错误原因码清零。看门狗定时器在此时启动,确保整个初始化过程不会无限期卡住。
Master 在 Reset 状态主动发送 Reset 命令帧,等待 Slave 的回应。规范对此有一个有趣的细节:如果 Master 收到的 Slave 回应中 Command 不是 Reset(意味着对方处于错误的状态),Master 并不会立即报错——它会再次发送 Reset 帧并重置内部变量,给对方一个"校正"的机会。只有当对方发送了合法的 Reset 响应后,Master 才会生成一个随机的 Session ID 并主动发起向 Session 状态的跃迁。
Slave 在 Reset 状态下则处于被动等待模式。它监听 Master 发来的命令,一旦收到合法的 Reset 帧,就回应 Reset 帧并准备好接收 Session 帧。如果 Slave 收到的不是 Reset 命令(例如收到了 Session 或 Data 命令——意味着 Master 认为连接已经建立),Slave 会回应 Reset 帧并报告"非预期命令"错误。
Reset 状态下不存在 Connection ID(ConnID = 0),CRC 校验使用简化的计算方式,因为此时还没有建立 CRC 继承链。看门狗在 Reset 状态下同样有效——如果规定时间内收不到有效报文,Master 和 Slave 各自独立超时,重新初始化并再次尝试发起连接。
Session 状态的核心目标是建立一次通信会话的唯一性标识——Session ID。
Master 在进入 Session 状态之前,调用 CREATE_SESSION_ID() 生成一个随机的 16 位 Session ID,然后通过 Session 命令帧发送给 Slave。Slave 收到后,并非简单回传——它同样调用 CREATE_SESSION_ID() 独立生成自己的随机 Session ID,然后通过 Session 帧发回给 Master。这样双方各自贡献了随机性,两个 Session ID 随后都被纳入 CRC 计算,确保了双向的会话唯一性。
这个设计解决了一个微妙的安全问题:假设设备在运行中经历了短暂的断电(例如电源抖动),Master 和 Slave 的序列号恰好回到了相近的值。如果没有 Session ID 的变化,重新上电后的通信可能与断电前的通信在 CRC 层面"混淆"——上一次通信残留在内存中的 CRC_0 值可能恰好匹配新通信的 CRC 值。Session ID 的重新随机化彻底消除了这种跨上电周期的混淆可能。
Session 状态下的数据交换采用分段传输。Session ID 是一个 16 位的值,占用 2 个字节,刚好对应一个最短安全数据长度。如果 Session ID 被完整接收且 CRC 校验通过(BytesToBeSent = 0),Master 转入 Connection 状态。如果 CRC 校验失败,Master 会重试一次(SecondSessionFrameSent 标志),再次失败则回到 Reset 状态并报告 CRC 错误。
一个值得注意的细节:在 Session 状态中,如果 Master 收到了 Connection、Parameter、ProcessData 或 FailSafeData 命令——即对方跳过了 Session 状态——Master 会立即回到 Reset 并报告"非预期命令"错误。这种严格的状态检查确保通信握手不会被跳过或绕开。
Connection 状态完成两项关键任务:下发 Connection ID 和 绑定 FSoE Slave Address。
ConnData 是一个由安全配置工具(Safety Configurator)预先配置的数据结构,包含 Connection ID 和 FSoE Slave Address 两个字段。Connection 状态中,Master 将 ConnData 通过 Connection 命令帧发送给 Slave,Slave 收到后存储这两个值。
Connection ID 是一个 16 位的唯一标识符,在整个 FSoE 网络中必须唯一。此后所有数据交换阶段的 PDU 都将携带这个 ConnID,接收方通过校验 ConnID 来确认"这个报文确实是发给我的"。FSoE Slave Address 则是在 Connection 状态中被 Slave 接受并存储——后续 Slave 会持续校验收到的 ConnID 是否与自身存储的一致。
Connection 状态的分段传输最复杂:ConnData 共 4 个字节(2 字节 ConnID + 2 字节 Slave Address),如果安全数据长度不足以一次传输完,需要分多帧发送。每帧发送后 BytesToBeSent 递减,直到全部 4 字节发送完毕。只有当所有 4 个字节都被正确接收、安全数据回显校验通过(IS_SAFEDATA_CORRECT)、CRC 校验通过,且 Frame.ConnId 与配置的 ConnData.ConnId 一致时,Master 才转入 Parameter 状态。
Slave 在 Connection 状态中的行为有一个关键的安全设计:它会将收到的 ConnData 中的 Slave Address 与自身的拨码开关或配置值进行比对。如果地址不匹配,Slave 回应 Reset 并报告 INVALID_ADDRESS 错误——这拦截了组态配置中的寻址错误。
Parameter 状态是进入正常数据交换前的最后一道关卡,负责协商通信双方的安全运行参数。
SafePara 包含两类参数。第一类是安全通信参数,核心是 FSoE 看门狗时间(Watchdog Time)——它决定了通信丢失后多长时间进入安全状态。看门狗时间在 1-65535 ms 范围内可配,必须同时在 Master 和 Slave 侧匹配。第二类是安全应用参数,与应用相关,例如安全数据的长度、安全功能的具体配置等。
Parameter 状态的传输有一个显著特点:参数数据可能非常大。与 Session ID 仅 2 字节、ConnData 仅 4 字节不同,SafePara 可能包含数十甚至上百字节的安全应用参数。因此 Parameter 状态的分段传输可能跨越多个 FSoE 周期。规范使用 BytesToBeSent 变量和 UPDATE_BYTES_TO_BE_SENT 宏来精确跟踪剩余待传输的字节数。
每收到一个 Parameter 帧,Slave 不仅校验 CRC 和 ConnID,还会调用 IS_SAFE_PARA_CORRECT 宏逐条检查参数的有效性——通信参数长度是否正确、参数值是否在合法范围内、应用参数是否与设备能力匹配。任何一条检查失败,Slave 都会报告 INVALID_DATA 或 FAULTY_SAFE_PARA 错误并回到 Reset 状态。
参数协商成功后(PARA_OK),Master 发送第一个 Data 命令帧。初始的 DataCommand 为 FailSafeData——意味着即使进入了 Data 状态,安全输出最初仍然是关闭的,需要应用层通过 Set Data Command 事件主动切换为 ProcessData 才能真正激活安全输出。这种"进入 Data 但仍先保持安全输出关闭"的设计确保应用层有足够的初始化时间。
Data 状态是 FSoE 运行时间最长的状态——一旦建立,Stay 在这里,直到通信出错或主动复位。
Data 状态的核心循环非常简洁:Master 发送携带 SafeOutputs 的 ProcessData(或 FailSafeData)命令帧,Slave 接收到后提取安全输出数据、执行本地安全动作、将 SafeInputs 打包进 ProcessData(或 FailSafeData)命令帧回传给 Master。每个周期中,CRC 继承链、序列号递增和看门狗重置同步进行。
Data 状态有两个子模式:ProcessData(正常模式)和 FailSafeData(故障安全模式)。两者在 PDU 格式上完全一致,区别仅在于 Command 字节——0x36 对 0x08——以及 SafeData 的值。在 FailSafeData 模式下,安全数据被强制设为全零(FS_VALUE),无论应用层请求是什么。Master 和 Slave 都可以通过 Set Data Command 事件在两种模式之间切换,且对方的回应模式不影响己方的发送模式——Slave 发送 FailSafeData 并不意味着 Slave 要求 Master 也发送 FailSafeData,反之亦然。
ETG.5100 规范对 Data 状态下的 CRC 校验有额外的严格约束。如果 CRC 校验失败,即使 ConnID 匹配,接收方也立即进入 Reset 状态并报告 INVALID_CRC。序列号(虚拟的,不出现在 PDU 中但纳入了 CRC 计算)的不连续同样会被 CRC 校验捕获——因为接收方维护自己的 MasterSeqNo/SlaveSeqNo 预期值,任何跳变都会导致 CRC 不匹配。
看门狗在 Data 状态下的角色尤为关键。每一个接收到的有效 ProcessData 或 FailSafeData 帧都会重置看门狗定时器——但无效帧(CRC 错误、ConnID 不匹配)不会。这意味着即使通信链路没有完全中断,持续收到损坏的报文同样会导致看门狗超时,触发进入 Reset 状态。
Master 和 Slave 的状态机在整体结构上高度对称——五个状态完全相同,转换触发条件也基本对应。ETG.5100 规范分别以 Figure 7 和 Figure 8 给出了两者的状态图。

图2 FSoE Master 状态机
▲ ETG.5100 Figure 7 – FSoE Master 状态机。与 Slave(Figure 8)相比,两者状态相同但发起权和错误回归路径存在关键差异。
发起权的不对称。Reset → Session 的跃迁只能由 Master 发起(通过生成 Session ID 并发送 Session 帧)。Slave 在 Reset 状态下只能被动的响应 Reset 帧,然后等待 Master 发起 Session。这种不对称反映了 FSoE 的 Master-Slave 体系结构:Master 是通信的管理者,Slave 是响应者。
失败后的回归路径不同。当 Master 在 Session、Connection、Parameter 或 Data 状态检测到错误时,它会回到 Reset 状态,然后立即重新生成 Session ID 并发起 Session 帧——即自动尝试重建连接。而当 Slave 在这些状态检测到错误时,它回到 Reset 状态后只是等待。这种差异意味着 Slave 永远不会"主动出击"——只有 Master 有重建连接的决定权。
Data 状态下的自主安全响应。在 Data 状态下,Slave 的自主性体现在错误响应上——如果 Slave 的看门狗超时(DATA_WD),它独立进入 Reset 状态并停止所有安全输出,不依赖 Master 的任何指令。这是黑色通道原理在状态机层面的核心体现:Slave 不需要知道"通信为什么断了",它只需要知道"通信断了",然后自行进入安全状态。
FSoE 的状态机不只是五个状态的简单切换,它是一部精确到每个事件、每个条件、每个动作的安全通信"宪法"。从 Reset 的全变量清零,到 Session 的随机数种子,到 Connection 的身份绑定,到 Parameter 的能力协商,再到 Data 的持续监控——每一步都在为最终的 SIL3 安全等级添砖加瓦。
将状态机与前面四篇文章的知识串联起来,整体图景已经非常清晰:黑色通道原理定义了"底层不可信"的前提(第一篇),四道安全防线在逻辑上部署了防御体系(第二篇),多 CPU 冗余在硬件上保证了执行单元的可靠性(第三篇),安全 PDU 在帧格式层面编码了所有防护手段(第四篇),而状态机将这些机制组织成了一套有节奏、有纪律的运行规则(本文)。
在下一篇文章中,我们将介绍 FSoE 的安全反应时间模型,分析从安全事件发生到执行器进入安全状态的完整时序链条。
参考:ETG.5100 Safety over EtherCAT Specification V1.2.0 / ETG.5101 FSoE Implementation Guide V1.3.0 / IEC 61784-3 / FSoE 协议基础介绍 V1.0