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,用于单片的追溯和良率分析。
下面这张图展示了事件在“设备—配方—批次—晶圆”四层对象之间的关联结构,以及事件从触发到归档的流转路径。图中同时标出了原生事件、合成事件和系统事件三类来源,便于理解事件模型的整体布局。
五、建模落地:从事件表到追溯查询
实际落地时,建议把事件模型拆成三张表: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 的初始化时机。
事件模型设计不是一次性的工作。随着设备类型增加、配方版本迭代、批次结构变化,事件分类和关联关系都需要持续维护。建议每季度做一次事件模型评审,重点检查:新增设备是否复用了已有事件类型、合成事件的触发条件是否仍然准确、关联表是否出现孤儿记录。只有把事件模型当作“活”的资产来管理,设备追溯系统才能真正做到“查得到、查得准、查得快”。