docs: chapters 02 + 03 of the guided tour (Part 1 complete)
02 — The cast of characters: equipment, EAP, MES, fab planner, AMHS, operator. Who initiates which conversation, why the equipment is the passive side of HSMS by convention, how the AMHS handshake is out-of-band relative to SECS. Cross-references the relevant namespace and test files for each actor. 03 — Vocabulary + a wafer's journey: follows one 300 mm wafer end-to-end through a fab and labels every SECS message and acronym that fires. Introduces SVID / DVID / ECID / CEID / RPTID / ALID / PPID / MDLN / SOFTREV / HCACK / ALCD / OFLACK / CAACK / SMACK / etc. in context rather than as a list. Includes one-screen reference tables for the remaining acknowledge codes, T-timers in all four contexts (HSMS / SECS-I / E84 / E30 communication state), and a stream-by-stream summary. Part 1 (Foundations) of the guided tour is now complete — a reader who reads chapters 01–03 can describe the protocol stack, identify the actors, and recognise every acronym they'll meet in Part 2. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,417 @@
|
||||
# 02 — The cast of characters
|
||||
|
||||
← [01 What is SECS/GEM?](01_what_is_secs_gem.md) | [Back to index](00_index.md) | Next: [03 Vocabulary + a wafer's journey](03_vocabulary_and_a_wafers_journey.md) →
|
||||
|
||||
Chapter [01](01_what_is_secs_gem.md) explained that SECS/GEM is the
|
||||
protocol a fab uses to make ~100 tools talk to a central MES. That
|
||||
description hid a lot of structure. In reality, there are at least
|
||||
**six distinct actors** in a typical fab automation stack — six
|
||||
roles, each implemented by different software (often by different
|
||||
vendors), each with its own concerns.
|
||||
|
||||
This chapter introduces them all, draws who-talks-to-whom, and
|
||||
locates each one in this codebase. After this you'll be able to read
|
||||
any SECS conversation and know which actor is initiating, which is
|
||||
responding, and why.
|
||||
|
||||
---
|
||||
|
||||
## The six actors
|
||||
|
||||
```
|
||||
┌──────────────────┐
|
||||
│ Fab planner │ "make 100 wafers
|
||||
│ (MES upper) │ of recipe R by
|
||||
└────────┬─────────┘ Friday"
|
||||
│
|
||||
recipes, lot │ yields, KPIs,
|
||||
assignments, │ alarms, status
|
||||
process programs │
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ MES (the host) │ per-step orchestration
|
||||
└────────┬─────────┘
|
||||
│
|
||||
SECS/GEM │ SECS/GEM
|
||||
S2F41 RCMD, │ S6F11 events,
|
||||
S7F3 PP send, │ S5F1 alarms,
|
||||
S2F33 reports, │ S1F4 status
|
||||
… │ …
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ EAP / equipment automation program │
|
||||
│ (vendor application layer) │
|
||||
├──────────────────────────────────────────┤
|
||||
│ THIS CODEBASE — the SECS/GEM runtime │
|
||||
│ secsgem::gem / secsgem::hsms / … │
|
||||
└────────┬─────────────────────────────────┘
|
||||
│
|
||||
PLC / sensor / recipe-engine APIs (tool-specific)
|
||||
│
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ Equipment │ the physical tool:
|
||||
│ (the tool) │ chambers, robots,
|
||||
└────────┬─────────┘ sensors, recipes
|
||||
│
|
||||
E84 8-line │ (carrier moves, no SECS bytes)
|
||||
parallel I/O │
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ AMHS │ robot rails / OHT
|
||||
│ (the carriers) │ that move FOUPs
|
||||
└──────────────────┘
|
||||
|
||||
←───── Operator ──────→ panel buttons,
|
||||
recipe overrides,
|
||||
Online/Offline/Local/Remote
|
||||
```
|
||||
|
||||
Read the diagram top-down: a fab planner schedules work, the MES
|
||||
dispatches it tool by tool, each tool's EAP receives commands over
|
||||
SECS/GEM, the EAP drives the actual hardware, the AMHS robots feed
|
||||
carriers in and out. An operator can intervene at any layer.
|
||||
|
||||
Each actor has a section below.
|
||||
|
||||
---
|
||||
|
||||
## 1. Equipment — the tool itself
|
||||
|
||||
**What it is.** A physical processing tool — a chemical-vapor
|
||||
deposition (CVD) chamber, a plasma etcher, a wafer prober, a
|
||||
photolithography stepper, an ion implanter, an inspection
|
||||
microscope. Anywhere from one chamber the size of a microwave to a
|
||||
full lithography cluster the size of a small bus.
|
||||
|
||||
**What it does in SECS/GEM terms.**
|
||||
|
||||
- **Reports state** — its current control state (Equipment Offline,
|
||||
Online Remote, …), its processing state (IDLE, EXECUTING, …), its
|
||||
carrier slots, its current recipe.
|
||||
- **Emits events** — when something happens worth recording
|
||||
(processing started, wafer processed, alarm raised, recipe
|
||||
completed), it fires an `S6F11` to the host.
|
||||
- **Accepts commands** — START, STOP, ABORT, PAUSE, CHANGE-RECIPE,
|
||||
CARRIER-PROCEED, etc., delivered as `S2F41` Host Commands.
|
||||
- **Stores its data dictionary** — every Status Variable (SVID),
|
||||
Equipment Constant (ECID), Data Variable (DVID), Collection Event
|
||||
(CEID), Alarm (ALID), and Process Program (PPID) it supports.
|
||||
- **Manages its own physical safety** — it can refuse a host command
|
||||
if the requested action would damage hardware, and it can raise
|
||||
alarms autonomously.
|
||||
|
||||
**In SECS/GEM, the equipment is almost always the "passive" side of
|
||||
the connection** — it binds a TCP port and waits for the host to
|
||||
connect, rather than the other way around. This codebase reflects
|
||||
that: `apps/secs_server.cpp` is the equipment, and it listens.
|
||||
|
||||
**Where it lives in this codebase.**
|
||||
|
||||
- The equipment role's main binary: [`apps/secs_server.cpp`](../apps/secs_server.cpp).
|
||||
- The data dictionary: [`include/secsgem/gem/data_model.hpp`](../include/secsgem/gem/data_model.hpp)
|
||||
defines `EquipmentDataModel`, which composes every per-domain
|
||||
store (SVIDs, ECIDs, CEIDs, alarms, carriers, substrates, recipes,
|
||||
spool, …).
|
||||
- A worked example with sensor simulation, recipe runner, and alarm
|
||||
monitoring: [`examples/pvd_tool/main.cpp`](../examples/pvd_tool/main.cpp).
|
||||
- Tests covering equipment behaviour: [`tests/test_data_model.cpp`](../tests/test_data_model.cpp),
|
||||
[`tests/test_control_state.cpp`](../tests/test_control_state.cpp),
|
||||
[`tests/test_host_handler.cpp`](../tests/test_host_handler.cpp).
|
||||
|
||||
---
|
||||
|
||||
## 2. EAP — the equipment automation program
|
||||
|
||||
**What it is.** The vendor-written software layer that sits on top
|
||||
of the SECS/GEM runtime and *makes the tool actually do things*.
|
||||
The EAP is the glue between:
|
||||
|
||||
- The SECS/GEM library (this codebase),
|
||||
- The tool's PLCs / sensors / recipe engine / robot controllers,
|
||||
- The tool vendor's domain logic.
|
||||
|
||||
Every tool vendor ships their own EAP. Two CVD tools from different
|
||||
vendors both speak GEM, but their EAPs are entirely different
|
||||
codebases doing entirely different things internally.
|
||||
|
||||
**Why it's a separate role.** The SECS/GEM standards spell out
|
||||
*what* messages mean — "S2F41 with RCMD=START must initiate
|
||||
processing on the currently loaded recipe." They don't spell out
|
||||
*how* a specific CVD tool initiates processing on its specific
|
||||
hardware. The EAP is the layer that resolves that.
|
||||
|
||||
In particular:
|
||||
|
||||
- When `S2F41 RCMD=START` arrives, the EAP decides whether the tool
|
||||
is in a state to start (chamber pressure low enough? robot at
|
||||
home position? recipe loaded?), and if so, calls the tool's
|
||||
proprietary recipe engine to begin the cycle.
|
||||
- When a sensor reads a temperature change, the EAP decides whether
|
||||
to update an SVID, fire a CEID, or raise an alarm — and the
|
||||
per-tool rules for that aren't in any SEMI standard.
|
||||
- When a `S7F3` arrives with a new recipe payload, the EAP decides
|
||||
how to validate the recipe against the tool's actual hardware
|
||||
capabilities.
|
||||
|
||||
**Where it lives in this codebase.**
|
||||
|
||||
This codebase provides the SECS/GEM runtime; the EAP is what a
|
||||
customer writes on top of it. We ship two reference EAPs:
|
||||
|
||||
- [`apps/secs_server.cpp`](../apps/secs_server.cpp) — the demo
|
||||
server. Wires every Router handler the demo flow needs; uses
|
||||
static YAML data and doesn't simulate any sensors. Useful as a
|
||||
starting fork.
|
||||
- [`examples/pvd_tool/main.cpp`](../examples/pvd_tool/main.cpp) — a
|
||||
fictional PVD tool that adds a sensor simulator, a recipe runner,
|
||||
an alarm threshold monitor, EPT state cycling, and Prometheus
|
||||
metrics. This is the closest thing to "what a real EAP looks
|
||||
like" that we ship. See [`examples/pvd_tool/README.md`](../examples/pvd_tool/README.md)
|
||||
for the section-by-section walk.
|
||||
|
||||
The integration tutorial — how to *write* an EAP for a real tool —
|
||||
is [`INTEGRATION.md`](INTEGRATION.md). Chapter
|
||||
[41](41_integration_hardware_mes_production.md) in this series covers
|
||||
the same material with cross-references back to the standards.
|
||||
|
||||
---
|
||||
|
||||
## 3. MES — the host
|
||||
|
||||
**What it is.** The **Manufacturing Execution System**. A
|
||||
fab-wide server (or cluster) that orchestrates production across
|
||||
every tool, manages lots and recipes, collects yield and statistical
|
||||
process control (SPC) data, and provides the operator UI for the
|
||||
production floor.
|
||||
|
||||
Commercial MES vendors you'll meet: Applied Materials **E3**, Camstar
|
||||
**InSite**, Wonderware **MES**, Aegis **FactoryWorks**, Inficon
|
||||
**FabGuard**, Critical Manufacturing **MES**, and many in-house
|
||||
custom builds especially at the largest fabs.
|
||||
|
||||
**What it does in SECS/GEM terms.**
|
||||
|
||||
- **Connects** to each tool's equipment process. In SECS/GEM
|
||||
language, the MES is the **active** side of the HSMS connection
|
||||
(it initiates the TCP connect and sends `Select.req`).
|
||||
- **Establishes communications** — sends `S1F13` to which the
|
||||
equipment replies `S1F14(COMMACK=Accept)`.
|
||||
- **Identifies the tool** — sends `S1F1` (Are You There), reads
|
||||
back the `MDLN` (model name) and `SOFTREV` (software revision)
|
||||
in `S1F2`.
|
||||
- **Reads the data dictionary** — `S1F11` for the SVID namelist,
|
||||
`S2F29` for the ECID namelist, `S1F23` for the CEID namelist,
|
||||
`S5F5` for the alarm directory, `S7F19` for the recipe list.
|
||||
- **Configures event reports** — `S2F33` defines a report,
|
||||
`S2F35` links it to a Collection Event, `S2F37` enables it. This
|
||||
is how the MES tells the tool "when CEID 300 fires, send me the
|
||||
values of SVIDs 1 and 2 along with it."
|
||||
- **Issues remote commands** — `S2F41 RCMD=START`, `S2F41
|
||||
RCMD=PAUSE`, `S2F41 RCMD=ABORT`, etc.
|
||||
- **Manages recipes** — `S7F3` to send a recipe, `S7F19` to list,
|
||||
`S7F17` to delete, `S7F5` to read one back.
|
||||
- **Orchestrates process and control jobs** — `S16F11` to create
|
||||
a Process Job, `S14F9` to wrap it in a Control Job, `S16F27`
|
||||
CJSTART to begin execution.
|
||||
- **Receives alarms and events** — `S5F1` for alarm set/clear,
|
||||
`S6F11` for collection events. Acknowledges with `S5F2` and
|
||||
`S6F12` respectively.
|
||||
- **Sets and reads the equipment's clock** — `S2F17`/`S2F18` to
|
||||
read, `S2F31`/`S2F32` to set.
|
||||
|
||||
**Where it lives in this codebase.**
|
||||
|
||||
We don't *implement* an MES — that's a separate, much larger product
|
||||
category. We implement the host *side* of SECS/GEM so the codebase
|
||||
can drive equipment too, mainly for testing.
|
||||
|
||||
- [`apps/secs_client.cpp`](../apps/secs_client.cpp) — the active
|
||||
host that drives the demo server through ~24 transactions.
|
||||
- [`apps/secs_conformance.cpp`](../apps/secs_conformance.cpp) — the
|
||||
host-driven conformance harness that runs the 47 wire-level checks.
|
||||
- [`include/secsgem/gem/host_handler.hpp`](../include/secsgem/gem/host_handler.hpp)
|
||||
+ [`src/gem/host_handler.cpp`](../src/gem/host_handler.cpp) —
|
||||
symmetric handler module so the host side can decode equipment
|
||||
replies and act on equipment-initiated S5F1 / S6F11.
|
||||
- [`interop/host_vs_cpp_server.py`](../interop/host_vs_cpp_server.py)
|
||||
— the secsgem-py active host driving our C++ passive server.
|
||||
|
||||
For integrating against a **commercial** MES,
|
||||
[`MES_INTEROP.md`](MES_INTEROP.md) is the day-1 punch list.
|
||||
|
||||
---
|
||||
|
||||
## 4. Fab planner / MES upper layer
|
||||
|
||||
**What it is.** The layer *above* the MES. Goes by many names:
|
||||
**Advanced Planning and Scheduling (APS)**, **Fab scheduler**,
|
||||
**Dispatcher**, **MES upper**. Big fabs separate this from the
|
||||
operational MES; smaller ones bundle it in.
|
||||
|
||||
**What it does.** Decides which lot runs on which tool, in what
|
||||
order, against what recipe, by what deadline. This is fab-wide
|
||||
optimisation across hundreds of in-flight lots and dozens of routes.
|
||||
|
||||
**SECS/GEM contact:** none directly. The planner talks to the MES
|
||||
via REST / SQL / a message queue / a proprietary API. The MES
|
||||
translates planner decisions into SECS commands.
|
||||
|
||||
**Where it lives in this codebase.** Not implemented; out of scope.
|
||||
Mentioned here so the reader knows where the recipes and lot
|
||||
assignments ultimately come from, but no codebase artifact
|
||||
corresponds to this layer.
|
||||
|
||||
---
|
||||
|
||||
## 5. AMHS — Automated Material Handling System
|
||||
|
||||
**What it is.** The robot-rail network and overhead hoist transport
|
||||
(**OHT**) system that physically moves carriers (FOUPs holding ~25
|
||||
wafers each) between tools. In a modern 300 mm fab the AMHS is
|
||||
*always* moving carriers between tools 24/7; humans never touch a
|
||||
substrate.
|
||||
|
||||
**What it does in SECS/GEM terms.**
|
||||
|
||||
- The AMHS itself **doesn't speak SECS/GEM** — it has its own
|
||||
control plane talking to a Material Control System (MCS) which is
|
||||
conceptually peer to the MES.
|
||||
- But every time a carrier *arrives at* or *departs from* an
|
||||
equipment's load port, the AMHS-side robot and the equipment-side
|
||||
load port **handshake over 8 parallel I/O lines** defined by
|
||||
**E84**. This is a physical-layer handshake (CMOS-level voltages
|
||||
on real wires) with strict timing — TA1, TA2, TA3 timers — to
|
||||
make sure a $20 000 FOUP doesn't get dropped because both sides
|
||||
thought the other one was holding it.
|
||||
- Once the carrier is physically docked, the equipment fires a
|
||||
`S6F11(CarrierArrived)` event to the MES and the MES sends back a
|
||||
`S3F17(CarrierAction=ProceedWithCarrier)` to authorise processing.
|
||||
|
||||
**Where it lives in this codebase.**
|
||||
|
||||
- The E84 handshake state machine: [`include/secsgem/gem/e84.hpp`](../include/secsgem/gem/e84.hpp)
|
||||
+ [`src/gem/e84.cpp`](../src/gem/e84.cpp).
|
||||
- The TA1/TA2/TA3 timer wiring: [`include/secsgem/gem/e84_timers.hpp`](../include/secsgem/gem/e84_timers.hpp),
|
||||
[`include/secsgem/gem/e84_asio_timers.hpp`](../include/secsgem/gem/e84_asio_timers.hpp).
|
||||
- The per-port store: `e84_ports.hpp` (see [`include/secsgem/gem/e84_ports.hpp`](../include/secsgem/gem/e84_ports.hpp)).
|
||||
- Tests covering the timing rules: [`tests/test_e84.cpp`](../tests/test_e84.cpp),
|
||||
[`tests/test_e84_timers.cpp`](../tests/test_e84_timers.cpp),
|
||||
[`tests/test_e84_asio_timers.cpp`](../tests/test_e84_asio_timers.cpp),
|
||||
[`tests/test_e84_ports.cpp`](../tests/test_e84_ports.cpp).
|
||||
|
||||
Chapter [18](18_e84_parallel_io.md) covers E84 in full.
|
||||
|
||||
---
|
||||
|
||||
## 6. Operator — the human
|
||||
|
||||
**What it is.** The fab technician at the tool's local panel. Their
|
||||
job is to handle anything the automation can't: load a non-AMHS
|
||||
carrier, clear a jammed wafer, run a maintenance recipe, respond to
|
||||
an alarm the MES can't auto-clear.
|
||||
|
||||
**What they do in SECS/GEM terms.**
|
||||
|
||||
- **Mode switch.** The operator can push the equipment between
|
||||
control states: `EquipmentOffline`, `OnlineLocal` (commands
|
||||
accepted only from the local panel), `OnlineRemote` (commands
|
||||
accepted from the MES). This is E30 §6.2.
|
||||
- **Override.** An operator can override an MES command (refuse to
|
||||
start, force-clear an alarm, manually unload a carrier). In
|
||||
SECS/GEM terms this is reflected by control-state transitions:
|
||||
`OnlineRemote` → `OnlineLocal` means "operator has taken control."
|
||||
- **Local alarm acknowledgement.** Some alarms can be cleared at
|
||||
the panel without the MES being involved; the equipment then
|
||||
emits an `S5F1` with the cleared bit so the MES catches up.
|
||||
|
||||
**Where it lives in this codebase.**
|
||||
|
||||
- The control state machine: [`include/secsgem/gem/control_state.hpp`](../include/secsgem/gem/control_state.hpp)
|
||||
+ [`src/gem/control_state.cpp`](../src/gem/control_state.cpp).
|
||||
- The transition table loaded from YAML: [`data/control_state.yaml`](../data/control_state.yaml).
|
||||
- The operator-initiated transition handlers:
|
||||
`ControlStateMachine::operator_online`, `::operator_offline`,
|
||||
`::operator_local`, `::operator_remote` in the same header.
|
||||
- Tests: [`tests/test_control_state.cpp`](../tests/test_control_state.cpp).
|
||||
|
||||
Chapter [13](13_e30_gem.md) walks through control state in detail.
|
||||
|
||||
---
|
||||
|
||||
## Who talks to whom
|
||||
|
||||
A short reference table. "Init." marks who initiates the
|
||||
conversation; "Channel" marks the protocol layer.
|
||||
|
||||
| Pair | Init. | Channel | Examples |
|
||||
|----------------------------|------------|---------------------------------------------|-----------------------------------------------------------|
|
||||
| Planner ↔ MES | Planner | REST / SQL / queue (out of scope) | "run lot L on tool T with recipe R" |
|
||||
| MES ↔ EAP | MES | HSMS-SS (one TCP socket, equipment passive) | `S1F1`, `S2F41`, `S6F11`, `S5F1`, … |
|
||||
| MES ↔ EAP (multi-MES) | MES | HSMS-GS (one TCP socket, multiple sessions) | Same messages, demuxed by session_id |
|
||||
| EAP ↔ Equipment | Either | PLC / sensor APIs / recipe engine (tool-specific) | Out of scope of SECS/GEM |
|
||||
| AMHS ↔ Load port | AMHS | E84 8-line parallel I/O | VALID/CS_0/CS_1/TR_REQ/READY/BUSY/COMPT/CONT/L_REQ/U_REQ/ES |
|
||||
| MES ↔ EAP (carrier flow) | Equipment | HSMS | `S6F11(CarrierArrived)`, `S3F17(ProceedWithCarrier)` |
|
||||
| Operator ↔ Equipment | Operator | Local panel | Online/Offline buttons, alarm acks |
|
||||
|
||||
The four interesting things in this table:
|
||||
|
||||
1. **The MES is the active side, the equipment is the passive side.**
|
||||
Always. Equipment binds the port; MES connects to it. Some MES
|
||||
want this reversed and will negotiate, but the GEM default is
|
||||
equipment-passive.
|
||||
2. **One TCP socket per (MES, equipment) pair.** HSMS-SS doesn't
|
||||
multiplex; one connection serves one conversation. HSMS-GS adds
|
||||
session multiplexing on top.
|
||||
3. **Equipment-initiated traffic exists.** `S6F11` events and
|
||||
`S5F1` alarms fire from equipment to MES *autonomously*, not
|
||||
in reply to a host command. An EAP that never emits unsolicited
|
||||
traffic is broken.
|
||||
4. **The AMHS handshake is out-of-band relative to SECS/GEM.**
|
||||
E84's 8 parallel I/O lines are real wires with real voltages;
|
||||
the SECS messages that follow (`S6F11`, `S3F17`) are just the
|
||||
*bookkeeping* around a handoff that already happened in
|
||||
hardware.
|
||||
|
||||
---
|
||||
|
||||
## A small mental check
|
||||
|
||||
If you've internalised the chapter, you should be able to answer:
|
||||
|
||||
1. When the MES sends `S1F13`, who initiates the TCP connection?
|
||||
2. When a chamber pressure sensor reads out of range, who decides
|
||||
whether to fire `S5F1`?
|
||||
3. What language does the AMHS speak to the equipment to coordinate
|
||||
a FOUP handoff?
|
||||
4. Is the operator at the local panel a SECS/GEM actor?
|
||||
5. Is the fab planner a SECS/GEM actor?
|
||||
|
||||
Answers, in order:
|
||||
|
||||
1. The MES. The equipment is passive; it binds and waits. TCP
|
||||
connect is the MES's first move.
|
||||
2. The EAP (the vendor's application code on top of this library).
|
||||
The SECS/GEM library doesn't know what's a "normal" pressure;
|
||||
the EAP does. Once the EAP decides "this is alarm-worthy," it
|
||||
calls into the alarm store and the library emits `S5F1`.
|
||||
3. E84 8-line parallel I/O — physical wires, not SECS. After the
|
||||
handoff, the *bookkeeping* SECS messages (`S6F11`, `S3F17`) flow
|
||||
between equipment and MES.
|
||||
4. Yes — through E30 §6.2 control-state transitions. Not a SECS
|
||||
message *sender*, but a state-transition source the equipment
|
||||
has to report on.
|
||||
5. No. The planner talks to the MES; the MES talks to the EAP.
|
||||
The planner is invisible from the SECS wire.
|
||||
|
||||
---
|
||||
|
||||
## What's next
|
||||
|
||||
You now know who's in the room and who's talking to whom. The next
|
||||
chapter introduces the **vocabulary** — every SEMI acronym you'll
|
||||
read in a debug log (SVID, CEID, ALID, PPID, ALCD, HCACK, T-timers,
|
||||
…) — by tracing **one wafer's journey** end-to-end through a fab and
|
||||
labelling every SECS message that fires along the way.
|
||||
|
||||
Next: [→ 03 Vocabulary + a wafer's journey](03_vocabulary_and_a_wafers_journey.md)
|
||||
Reference in New Issue
Block a user