ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
packml.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file packml.h
6 * @brief PackML / OMAC packaging-machine state model (ISA-TR88.00.02) - the state engine + PackTags.
7 *
8 * Reference standard: ISA-TR88.00.02-2022, "Machine and Unit States: An Implementation Example of ISA-88"
9 * (ISBN 978-1-64331-224-8) - the OMAC PackML state model and PackTags. The 17-state model, the numeric
10 * StateCurrent values, the command set, and the transition graph below follow that document.
11 *
12 * PackML is the OMAC / ISA-88 state model that packaging and process machines expose so a line
13 * controller (usually over OPC UA) can command and observe them uniformly. Two pieces:
14 *
15 * - the **state machine**: 17 states (Stopped/Idle/Execute/Held/Suspended/Complete/Aborted plus the
16 * transient "acting" states Starting/Resetting/Holding/... that auto-advance when their action
17 * finishes) driven by the control commands (Reset/Start/Stop/Hold/Unhold/Suspend/Unsuspend/Abort/
18 * Clear). Stop and Abort are the near-universal transitions to the shutdown / fault branches.
19 * - the **PackTags**: the standard Command / Status / Admin tag groups the model surfaces - the current
20 * state + unit mode, the requested/actual machine speed, and the production counters.
21 *
22 * This is a pure, fixed-BSS service: no heap, no I/O. The state engine (pc_packml_command /
23 * pc_packml_state_complete) is a pure transition table; the owned service (pc_packml_svc_*) layers the
24 * PackTags + counters + timers on top for a machine to run directly. Host-tested (native_packml).
25 *
26 * @author Douglas Quigg (dstroy0)
27 * @date 2026
28 */
29
30#ifndef PROTOCORE_PACKML_H
31#define PROTOCORE_PACKML_H
32
33#include "protocore_config.h"
34
35#if PC_ENABLE_PACKML
36
37#include <stdint.h>
38
39/**
40 * @brief PackML unit / machine state. The underlying value is the ISA-TR88.00.02 StateCurrent wire number
41 * (1..17), so casting to the byte a PackTags Status.StateCurrent carries is a no-op at the boundary.
42 */
43enum class PackMlState : uint8_t
44{
45 UNDEFINED = 0, ///< not yet initialized
46 CLEARING = 1, ///< acting: clearing a fault (Aborted -> Stopped)
47 STOPPED = 2, ///< wait: powered, safe, not producing
48 STARTING = 3, ///< acting: Idle -> Execute
49 IDLE = 4, ///< wait: ready to start
50 SUSPENDED = 5, ///< wait: paused by an external condition (starved/blocked)
51 EXECUTE = 6, ///< wait/producing: the machine is doing its work
52 STOPPING = 7, ///< acting: -> Stopped
53 ABORTING = 8, ///< acting: -> Aborted (fault)
54 ABORTED = 9, ///< wait: faulted; needs Clear
55 HOLDING = 10, ///< acting: Execute -> Held
56 HELD = 11, ///< wait: production paused by the operator
57 UNHOLDING = 12, ///< acting: Held -> Execute
58 SUSPENDING = 13, ///< acting: Execute -> Suspended
59 UNSUSPENDING = 14, ///< acting: Suspended -> Execute
60 RESETTING = 15, ///< acting: Stopped/Complete -> Idle
61 COMPLETING = 16, ///< acting: Execute (production done) -> Complete
62 COMPLETE = 17 ///< wait: the production run finished
63};
64
65/** @brief PackML control command (the Command.CntrlCmd tag). Value is the conventional CntrlCmd number. */
66enum class PackMlCommand : uint8_t
67{
68 PC_NONE = 0,
69 RESET = 1,
70 START = 2,
71 STOP = 3,
72 HOLD = 4,
73 UNHOLD = 5,
74 SUSPEND = 6,
75 UNSUSPEND = 7,
76 ABORT = 8,
77 CLEAR = 9
78};
79
80/** @brief PackML unit mode (Command.UnitMode / Status.UnitModeCurrent). Producing is the full state model. */
81enum class PackMlMode : uint8_t
82{
83 PRODUCING = 1,
84 MAINTENANCE = 2,
85 MANUAL = 3
86};
87
88// ---------------------------------------------------------------------------
89// Pure state engine (no state stored here - the caller holds the current state)
90// ---------------------------------------------------------------------------
91
92/**
93 * @brief Apply a control command to a state and return the resulting state.
94 *
95 * Stop and Abort are the universal transitions (Abort from every state except the abort branch; Stop from
96 * every state except the abort branch and the already-stopping/stopped/clearing states). Otherwise only the
97 * command valid in @p s per the model transitions; an invalid command returns @p s unchanged.
98 */
99PackMlState pc_packml_command(PackMlState s, PackMlCommand c);
100
101/**
102 * @brief Advance an "acting" (transient) state to its target once its action completes (the SC / State
103 * Complete transition, e.g. Starting -> Execute, Aborting -> Aborted). A "wait" state is returned
104 * unchanged - only acting states auto-advance.
105 */
106PackMlState pc_packml_state_complete(PackMlState s);
107
108/** @brief The production cycle finished: Execute -> Completing. Any other state is returned unchanged. */
109PackMlState pc_packml_execute_complete(PackMlState s);
110
111/** @brief True if @p s is an acting (transient, auto-advancing) state rather than a wait (stable) state. */
112bool pc_packml_is_acting(PackMlState s);
113
114/** @brief True if @p c is a legal command in @p s (i.e. pc_packml_command would change the state). */
115bool pc_packml_command_valid(PackMlState s, PackMlCommand c);
116
117/** @brief Human-readable state name (e.g. "Execute") for an HMI / log. Never null. */
118const char *pc_packml_state_name(PackMlState s);
119
120/** @brief Human-readable command name (e.g. "Start"). Never null. */
121const char *pc_packml_command_name(PackMlCommand c);
122
123// ---------------------------------------------------------------------------
124// Owned service: the PackTags + counters + timers a machine runs directly (fixed BSS, one owner)
125// ---------------------------------------------------------------------------
126
127/** @brief Status PackTags snapshot (Status.*). */
128struct PackMlStatus
129{
130 PackMlState state_current; ///< Status.StateCurrent
131 PackMlMode unit_mode_current; ///< Status.UnitModeCurrent
132 float mach_speed_actual; ///< Status.MachSpeedActual
133 uint32_t state_current_ms; ///< time in the current state (ms), Admin.StateCurrentTime
134 uint32_t acc_time_since_reset_ms; ///< Admin.AccTimeSinceReset
135 uint32_t prod_processed; ///< Admin.ProdProcessedCount
136 uint32_t prod_defective; ///< Admin.ProdDefectiveCount
137};
138
139/** @brief Initialize the service: state = Stopped, unit mode @p mode, counters/speed cleared. */
140void pc_packml_svc_init(PackMlMode mode);
141
142/**
143 * @brief Apply a control command (Command.CntrlCmd) to the running service.
144 * @return true if the command was legal in the current state and the state advanced.
145 */
146bool pc_packml_svc_command(PackMlCommand c);
147
148/**
149 * @brief Signal that the current acting state's action has finished (the machine's State-Complete). Advances
150 * an acting state to its target; a no-op in a wait state.
151 * @return the new state.
152 */
153PackMlState pc_packml_svc_state_complete(void);
154
155/**
156 * @brief Signal one production unit finished while in Execute: increments ProdProcessedCount (and, if
157 * @p defective, ProdDefectiveCount). Does not itself leave Execute (call pc_packml_svc_complete_run
158 * to end the run).
159 */
160void pc_packml_svc_count(bool defective);
161
162/** @brief End the production run: Execute -> Completing (then State-Complete carries it to Complete). */
163bool pc_packml_svc_complete_run(void);
164
165/** @brief Request a unit-mode change. Allowed only in a stable, non-producing state (Stopped/Idle/Aborted). */
166bool pc_packml_svc_set_mode(PackMlMode mode);
167
168/** @brief Set the commanded machine speed (Command.MachSpeed); reflected as MachSpeedActual while in Execute. */
169void pc_packml_svc_set_speed(float mach_speed);
170
171/** @brief Current state. */
172PackMlState pc_packml_svc_state(void);
173
174/** @brief Fill @p out with the current Status/Admin tag snapshot. */
175void pc_packml_svc_status(PackMlStatus *out);
176
177#endif // PC_ENABLE_PACKML
178#endif // PROTOCORE_PACKML_H
User-facing configuration for ProtoCore.