E40 · E87 · E90 · E94 axes
GEM300 capability catalog
A declarative catalog in the SECS/GEM SDK that records, profile by profile, which GEM300 areas an equipment configuration covers and to what degree.
What it does
- Profiles of up to four capabilities on four axes: ProcessJob (E40), Carrier (E87), Substrate (E90) and ControlJob (E94).
- Each capability carries a status label, so a profile shows how far the equipment configuration covers each GEM300 area.
- Replace the complete list of profiles in one atomic step and get the new revision back.
- Snapshots keep their own copy, so later changes don't affect them.
- Try it in the GEM300 workspace of the SECS/GEM simulator.
Example
Each binding shows code from a real example file in the examples folder of the PDComm SDK. The source file and line range appear above the code.
GEM300 catalog in C
PdcommGem300CapabilityCatalog *catalog = NULL;
PdcommStatus status = pdcomm_gem300_capability_catalog_create(&options, &catalog);
if (status != PDCOMM_OK) return failed("catalog_create", status);
/* Each profile lists at most one capability per axis. */
const PdcommGem300Capability line_a[] = {
{"pj-model", 8, PDCOMM_GEM300_PROCESS_JOB, PDCOMM_GEM300_MODEL_ONLY, PDCOMM_GEM300_UNVERIFIED, 0},
{"carrier", 7, PDCOMM_GEM300_CARRIER, PDCOMM_GEM300_PLANNED, PDCOMM_GEM300_UNVERIFIED, 0},
};
const PdcommGem300Capability line_b[] = {
{"cj-trial", 8, PDCOMM_GEM300_CONTROL_JOB, PDCOMM_GEM300_EXPERIMENTAL, PDCOMM_GEM300_UNVERIFIED, 0},
};
const PdcommGem300CapabilityProfile profiles[] = {
{"LINE-A", 6, line_a, 2},
{"LINE-B", 6, line_b, 1},
};
uint64_t revision = 0;
uint8_t changed = 0;
/* Replace swaps the whole catalog atomically; equal contents keep the revision. */
status = pdcomm_gem300_capability_catalog_replace(catalog, profiles, 2, &revision, &changed);
if (status != PDCOMM_OK) {
pdcomm_gem300_capability_catalog_destroy(catalog);
return failed("catalog_replace", status);
}
printf("replace: revision %llu, changed %u\n", (unsigned long long)revision, (unsigned)changed);
/* A snapshot owns its copy and stays valid after the catalog changes. */
PdcommGem300CapabilitySnapshot *snapshot = NULL;
status = pdcomm_gem300_capability_catalog_snapshot(catalog, &snapshot);
pdcomm_gem300_capability_catalog_destroy(catalog);
if (status != PDCOMM_OK) return failed("catalog_snapshot", status);
int result = print_snapshot(snapshot);From the C example: create a capability catalog, replace its contents atomically with two profiles (at most one capability per axis), then take a snapshot and read it back. The catalog is local data, independent of any HSMS session, and needs a license for the gem300 module.
GEM300 catalog in C++
// Limits: 4 profiles, 4 capabilities per profile (one per axis), 16 in
// total, identifiers up to 32 bytes and 256 bytes altogether.
pdcomm::Gem300CapabilityCatalog catalog(pdcomm::gem300CapabilityOptions(4, 4, 16, 32, 32, 256));
const std::vector<pdcomm::Gem300CapabilityProfile> profiles = {
{"LINE-A",
{{"pj-model", Gem300CapabilityAxis::ProcessJob, Gem300CapabilityStatus::ModelOnly},
{"carrier", Gem300CapabilityAxis::Carrier, Gem300CapabilityStatus::Planned}}},
{"LINE-B", {{"cj-trial", Gem300CapabilityAxis::ControlJob, Gem300CapabilityStatus::Experimental}}},
};
// Replace swaps the whole catalog atomically; equal contents keep the revision.
const auto change = catalog.replace(profiles);
std::cout << "replace: revision " << change.revision << ", changed " << change.changed << "\n";
// A snapshot owns its copy and stays valid after the catalog changes.
const auto snapshot = catalog.snapshot();
const auto info = snapshot.info();
std::cout << "revision " << info.revision << ": " << info.profileCount << " profiles, "
<< info.capabilityCount << " capabilities\n";
for (std::size_t p = 0; p < info.profileCount; ++p) {
std::cout << "profile " << snapshot.profileId(p) << "\n";
for (std::size_t c = 0; c < snapshot.profileInfo(p).capabilityCount; ++c) {
const auto capability = snapshot.capabilityInfo(p, c);
std::cout << " " << snapshot.capabilityId(p, c) << " " << axisName(capability.axis) << " "
<< statusName(capability.status) << "\n";
}
}From the C++ example: pass the profile list to Gem300CapabilityCatalog::replace(), then read profiles and capabilities from the snapshot() copy. A failed call throws pdcomm::Error.
GEM300 catalog in .NET
PdcommRuntime.Initialize(args[0]);
// Limits: 4 profiles, 4 capabilities per profile (one per axis), 16 in total,
// identifiers up to 32 bytes and 256 bytes altogether.
using var catalog = new Gem300CapabilityCatalog(new Gem300CapabilityOptions(4, 4, 16, 32, 32, 256));
Gem300CapabilityProfile[] profiles =
[
new("LINE-A",
[
new("pj-model", Gem300Axis.ProcessJob, Gem300Status.ModelOnly),
new("carrier", Gem300Axis.Carrier, Gem300Status.Planned),
]),
new("LINE-B", [new("cj-trial", Gem300Axis.ControlJob, Gem300Status.Experimental)]),
];
// Replace swaps the whole catalog atomically; equal contents keep the revision.
Gem300CatalogChange change = catalog.Replace(profiles);
Console.WriteLine($"replace: revision {change.Revision}, changed {change.Changed}");
// A snapshot owns its copy and stays valid after the catalog changes.
using Gem300CapabilitySnapshot snapshot = catalog.Snapshot();
Gem300CapabilityCatalogInfo info = snapshot.GetInfo();
Console.WriteLine($"revision {info.Revision}: {info.ProfileCount} profiles, {info.CapabilityCount} capabilities");
for (nuint index = 0; index < info.ProfileCount; index++)
{
Gem300CapabilityProfile profile = snapshot.GetProfile(index);
Console.WriteLine($"profile {profile.Id}");
foreach (Gem300Capability capability in profile.Capabilities)
Console.WriteLine($" {capability.Id,-10} {capability.Axis,-11} {capability.Status}");
}From the .NET example: Gem300CapabilityCatalog.Replace takes the profile records and Snapshot().GetProfile reads them back. Without a gem300 license, PdcommException.Status is LicenseRequired.