3. EAP事件模型设计

EAP(Equipment Automation Program)事件模型是设备追溯系统的“神经末梢”。如果事件定义得含糊,后续的过程数据、SPC 告警、批次追溯都会变成一团乱麻。本节要解决的核心问题是:把设备上发生的“动作”抽象成可被系统识别、存储和关联的事件对象,并明确它与设备状态、配方、批次、晶圆之间的绑定关系。

一、事件分类:先分清“谁在说话”

EAP 事件通常来自三个层面,分类时建议按来源和语义双重维度切分:

  • 设备原生事件:由设备 SECS/GEM 接口直接上报,如 EquipmentEvent、ProcessStart、ProcessEnd、AlarmSet、AlarmClear。这类事件带有设备厂商定义的 CEID(Collection Event ID),是追溯的原始素材。
  • EAP 合成事件:EAP 根据多个原生事件或状态变化推断出来的业务事件,如 LotStart、LotComplete、WaferStart、WaferEnd、RecipeChanged。它们不一定有对应的 CEID,但更贴近 MES 和追溯的业务语义。
  • 系统事件:EAP 自身运行产生的事件,如 CommTimeout、HostCommandReceived、DataCollectionFailed。这类事件用于排障和系统健康度分析。

分类的价值在于:原生事件保证“不丢”,合成事件保证“可读”,系统事件保证“可查”。三者不能混在一个表里用同一套字段硬套。

二、事件触发条件:从“电平”到“边沿”

触发条件的设计要区分状态型和边沿型。状态型事件表示“当前处于什么状态”,如 EquipmentState = RUN;边沿型事件表示“刚刚发生了什么变化”,如 StateChanged: IDLE → RUN。追溯系统更关心边沿,因为边沿才对应时间点。

以 ProcessStart 为例,触发条件不能简单写成“设备开始加工”,而应明确为:设备状态从 IDLE 或 SETUP 迁移到 RUN,且 PP-SELECT 已确认、ControlState = REMOTE、ProcessJob 已下发。缺少任一条件,事件要么误触发,要么漏触发。

建议为每个事件定义“触发表达式”,例如:ProcessStart := (prevState ∈ {IDLE, SETUP}) ∧ (currState = RUN) ∧ (recipeId ≠ null) ∧ (lotId ≠ null)。表达式可以直接作为规则引擎的输入,避免硬编码。

三、事件生命周期:从产生到归档

一个事件对象通常经历以下阶段:产生(Raise)→ 接收(Receive)→ 关联(Correlate)→ 持久化(Persist)→ 发布(Publish)→ 归档(Archive)。其中“关联”是最容易被忽略但最关键的一步:EAP 收到 ProcessStart 后,必须立刻把它与当前的 lotId、waferId、recipeId、equipmentId 绑定,否则事件就只是一个孤立的信号。

生命周期中还要处理乱序和重复。设备上报可能延迟,EAP 合成事件可能先于原生事件到达。常见做法是给每个事件分配 eventTime(设备时间)和 receiveTime(EAP 时间),关联时以 eventTime 排序,并设置一个 500ms~2s 的关联窗口。重复事件则通过 eventId + equipmentId + eventTime 做幂等去重。

四、事件与设备状态、配方、批次、晶圆的关系建模

这是本节的核心。事件不是孤立的点,而是挂在“设备—配方—批次—晶圆”四层对象上的时间戳。建模时建议采用事件-对象关联表,而不是把 lotId、waferId 直接塞进事件主表。原因是一个事件可能同时关联多个对象,例如 ProcessEnd 既关联当前批次,也关联该批次下的所有晶圆。

关系可以这样定义:

  • 设备状态:事件发生时设备的 ControlState、ProcessState、CarrierState 快照,作为事件属性保存。
  • 配方:recipeId、recipeVersion、ppId,用于判断“这批货到底用的哪版配方”。
  • 批次:lotId、lotType、routeStep,用于把事件挂到 MES 的工单链上。
  • 晶圆:waferId、slotNo、waferSeq,用于单片的追溯和良率分析。

下面这张图展示了事件在“设备—配方—批次—晶圆”四层对象之间的关联结构,以及事件从触发到归档的流转路径。图中同时标出了原生事件、合成事件和系统事件三类来源,便于理解事件模型的整体布局。

EAP 事件模型:来源分类 · 生命周期 · 四层对象关联 事件来源 设备原生事件 CEID / ProcessStart AlarmSet / AlarmClear EAP 合成事件 LotStart / LotComplete WaferStart / RecipeChanged 系统事件 CommTimeout DataCollectionFailed 事件生命周期 ① 产生 Raise ② 接收 Receive ③ 关联 Correlate ④ 持久化 Persist ⑤ 发布 Publish ⑥ 归档 Archive 事件关联的四层对象 设备状态 Equipment State ControlState · ProcessState · CarrierState equipmentId · chamberId 配方 Recipe recipeId · recipeVersion · ppId stepNo · parameterSet 批次 Lot lotId · lotType · routeStep productId · priority 晶圆 Wafer waferId · slotNo · waferSeq substrateId · measurementData 关联窗口建议 500ms~2s;幂等键 = eventId + equipmentId + eventTime;eventTime 用于排序,receiveTime 用于延迟分析

五、建模落地:从事件表到追溯查询

实际落地时,建议把事件模型拆成三张表:event_master(事件主表,存 eventId、eventType、eventTime、receiveTime、sourceType)、event_context(事件上下文,存 equipmentId、stateSnapshot、recipeId、lotId)、event_wafer_link(事件-晶圆关联表,存 eventId、waferId、slotNo)。这样查询“某片晶圆在哪个步骤、用哪版配方、经历了哪些事件”时,只需要三表关联,而不需要扫描全量事件日志。

一个典型的追溯查询是:给定 waferId = W001-07,找出它在 LITHO-01 设备上 ProcessStart 到 ProcessEnd 之间的所有事件,并输出对应的 recipeVersion 和 lotId。如果事件模型设计正确,这个查询应该在毫秒级返回;如果设计错误,就会变成跨多个日志文件的模糊匹配。

常见错误:把 lotId 和 waferId 直接写死在事件主表里。当一批多片晶圆同时加工时,ProcessStart 只发生一次,但需要关联多片晶圆。正确做法是用关联表,而不是在事件主表里塞一个 waferId 字段。

六、事件触发条件配置示例

下面给出一个可直接参考的事件触发条件配置片段,用于 EAP 规则引擎。字段含义:eventName 为事件名,trigger 为触发表达式,correlate 为关联对象,windowMs 为关联窗口。

{
  "eventName": "ProcessStart",
  "trigger": "prevState in [IDLE, SETUP] and currState == RUN and recipeId != null and lotId != null",
  "correlate": ["equipmentId", "lotId", "recipeId", "waferId"],
  "windowMs": 1500,
  "source": "EAP_SYNTHETIC"
},
{
  "eventName": "WaferEnd",
  "trigger": "waferSeq == totalWaferCount and processState == RUN",
  "correlate": ["equipmentId", "lotId", "waferId", "slotNo"],
  "windowMs": 800,
  "source": "EAP_SYNTHETIC"
},
{
  "eventName": "AlarmSet",
  "trigger": "alarmCode != null and alarmState == SET",
  "correlate": ["equipmentId", "chamberId", "alarmCode"],
  "windowMs": 500,
  "source": "EQUIPMENT_NATIVE"
}

配置完成后,验证方法是:在设备上手动触发一次 ProcessStart,观察 EAP 日志中是否同时出现原生 CEID 事件和合成 ProcessStart 事件,并检查 event_context 表中 lotId、recipeId、waferId 是否全部非空。如果 waferId 为空,说明关联窗口太短或晶圆映射表未加载,需要调整 windowMs 或检查 waferMap 的初始化时机。

事件模型设计不是一次性的工作。随着设备类型增加、配方版本迭代、批次结构变化,事件分类和关联关系都需要持续维护。建议每季度做一次事件模型评审,重点检查:新增设备是否复用了已有事件类型、合成事件的触发条件是否仍然准确、关联表是否出现孤儿记录。只有把事件模型当作“活”的资产来管理,设备追溯系统才能真正做到“查得到、查得准、查得快”。