3. 有限状态机在设备控制中的实现

在半导体设备控制软件中,有限状态机(FSM)是把“设备当前处于什么状态、什么条件下允许迁移、迁移时执行什么动作”这三件事固定下来的核心手段。以腔室门控与机械手取放片为例:腔室门有开、关、锁定三种物理状态,机械手有回原点、伸入、夹持、缩回、放片等动作阶段,二者必须通过互锁条件协同,否则会出现撞门、掉片、真空破坏等严重事故。本节围绕同一控制对象,比较状态表驱动、状态模式、层次状态机三种实现方式的代码组织差异,并给出可落地的实现要点。

一、状态表驱动:把迁移规则外置为数据

状态表驱动的核心思想是:状态迁移不再散落在 if-else 中,而是集中为一张表。表的每一行描述一条迁移规则,字段通常包括:当前状态、触发事件、守卫条件、目标状态、进入动作、退出动作。以腔室门控为例,可定义如下状态表(示例参数,用于说明结构):

状态表(Door FSM)
当前状态   事件            守卫条件                 目标状态   动作
CLOSED     CMD_OPEN        vacuum_ok && robot_safe   OPENING    start_motor()
OPENING    SENSOR_OPEN     —                         OPEN       stop_motor()
OPENING    TIMEOUT_3S      —                         FAULT      raise_alarm(E01)
OPEN       CMD_CLOSE       robot_clear               CLOSING    start_motor()
CLOSING    SENSOR_CLOSED   —                         CLOSED     lock_pin()
CLOSING    TIMEOUT_3S      —                         FAULT      raise_alarm(E02)
FAULT      CMD_RESET       door_still && no_wafer     CLOSED     clear_alarm()

代码组织上,通常用一个枚举表示状态,一个结构体数组承载迁移表,主循环只做“查表—判断守卫—执行动作—更新状态”四步。这种方式的优点是:迁移规则可被工具解析、可生成文档、可做覆盖率检查;新增状态只需加行,不必改动主循环。缺点是守卫条件和动作函数仍需以函数指针或回调形式注册,表本身无法表达“状态内部还有子状态”的复杂语义。对于腔室门这种状态少、迁移明确的设备,状态表驱动是性价比最高的选择。

二、状态模式:把行为封装进状态对象

状态模式把每个状态封装为一个类,状态类持有设备上下文(Context)的引用,并在自身方法中决定何时调用 context->transitionTo(nextState)。以机械手取放片为例,可定义 RobotState 基类,派生 HomeState、ExtendState、GripState、RetractState、PlaceState。每个状态类实现 onEnter()、onEvent(event)、onExit() 三个接口。

与状态表相比,状态模式的优势在于:状态相关的数据(如伸出位置、夹持力设定值)可以自然成为状态对象的成员;复杂守卫逻辑可写成私有方法;新增状态符合开闭原则。代价是状态数量多时类数量膨胀,且迁移关系分散在各状态类中,不易一眼看全。工程上常把状态模式与状态表混合使用:用表描述“允许哪些迁移”,用状态对象实现“迁移时做什么”。

三、层次状态机(HSM):处理“大状态里套小状态”

腔室门控与机械手协同的真实场景中,常出现“机械手在腔室门关闭后才允许伸入”这类嵌套约束。若用扁平 FSM,需要把“门已关”作为机械手每个状态的守卫条件重复书写。HSM 引入父状态与子状态:父状态 ChamberReady 下挂 DoorClosed 与 DoorLocked 两个子状态,机械手状态机作为 ChamberReady 的并行区域或子区域。事件先由最内层子状态处理,未处理则冒泡到父状态。这样,“门未关”这一公共守卫只需在父状态写一次。

HSM 的代码组织通常包含:状态层级树、进入/退出顺序(先父后子进入,先子后父退出)、历史状态(H)与浅/深历史、以及跨层迁移。实现时可用状态图描述语言(如 UML statechart)生成骨架代码,再填充动作。对于本课程涉及的设备控制,建议:门控用状态表驱动,机械手用状态模式,二者协同层用 HSM 的并行区域表达互锁,避免把互锁条件散落到两个独立 FSM 中。

腔室门控与机械手取放片:三种 FSM 实现方式对比 状态表驱动 迁移表:状态 × 事件 × 守卫 主循环:查表 → 守卫 → 动作 动作:函数指针 / 回调注册 适合:门控等状态少、迁移明确的设备 状态模式 RobotState 基类 + 派生状态类 onEnter / onEvent / onExit 状态内数据与守卫私有化 适合:机械手等动作阶段多、数据随状态变化 层次状态机 HSM 父状态:ChamberReady 子状态:DoorClosed / DoorLocked 事件冒泡 + 并行区域互锁 适合:门控与机械手协同的嵌套约束 协同示例:门控 FSM 与机械手 FSM 的互锁信号链 门控 FSM CLOSED / OPEN / FAULT 互锁守卫 door_closed && vacuum_ok 机械手 FSM HOME / EXTEND / GRIP / PLACE 反馈:robot_clear / grip_ok / place_done 建议:门控用状态表驱动,机械手用状态模式,协同层用 HSM 并行区域表达互锁

四、三种方式的选型与落地建议

选型不应只看“先进程度”,而应看状态数量、迁移复杂度、协同层级和团队维护成本。门控状态少、迁移规则清晰,状态表驱动最易审查;机械手动作阶段多、每个阶段有独立参数,状态模式更自然;当门控与机械手需要共享“腔室就绪”这一父条件时,HSM 的层次与并行语义能显著减少重复守卫。实际工程中,三者常组合使用:用状态表生成迁移骨架,用状态模式实现动作,用 HSM 组织跨设备协同。

实现时注意三点:一是所有迁移必须经过守卫判断,禁止在动作函数中直接改状态;二是进入/退出动作要保证幂等,避免重复上电或重复夹持;三是超时迁移必须显式建模,如 OPENING 超时 3 秒进入 FAULT,而不是依赖外部看门狗。
常见错误:把互锁条件写在动作函数里而非守卫中,导致状态已迁移但条件不满足;或在 HSM 中忘记定义历史状态,导致父状态重入时子状态被错误复位。建议为每个 FSM 维护一张迁移覆盖表,确保每条迁移至少有一个测试用例。

综上,状态表驱动、状态模式与 HSM 并非互斥,而是分别解决“规则集中”“行为封装”“层级复用”三个问题。以腔室门控与机械手取放片为对象,先明确状态集合与迁移条件,再按复杂度选择实现方式,最后用互锁守卫和超时迁移保证安全性,才能让 FSM 真正成为设备控制软件中可验证、可维护的骨架。