Skip to content

Capstones

Capstones show source, runtime config, HMI files, and operator surfaces working together in one larger project.

Plant Demo

Docs category: docs/public/examples/capstones.md

This tutorial teaches how to navigate and debug a multi-file ST project in VS Code.

What You Learn

  • Type + FB + Program + Configuration layering
  • Cross-file navigation/refactor workflow
  • Debugging a state machine through scan cycles
  • Project config role (trust-lsp.toml)

Project Structure

  • src/types.st: shared enums/structs
  • src/fb_pump.st: PumpController state machine
  • src/program.st: orchestration logic (PlantProgram)
  • src/config.st: CONFIGURATION, TASK, program binding
  • trust-lsp.toml: indexing/profile settings for editor/runtime features

Step 1: Open and Build

code examples/plant_demo
trust-runtime build --project examples/plant_demo --sources src
trust-runtime validate --project examples/plant_demo

Step 2: Cross-File Navigation (Exact Keystrokes)

  1. Open src/program.st.
  2. Hold Ctrl and click PumpController -> lands in src/fb_pump.st.
  3. Press Alt+Left to go back.
  4. Place cursor on SpeedSet, press F2, enter PumpSpeedSet.
  5. Confirm rename preview includes all impacted references.
  6. Right-click PumpState -> Find All References (or Shift+F12).
  7. Verify references appear across multiple files.

Step 3: Debugger Walkthrough

  1. Open src/fb_pump.st.
  2. Set a breakpoint inside CASE Status.State OF.
  3. Press F5 (uses .vscode/launch.json).
  4. In Runtime Panel, toggle %IX0.0 (start signal).
  5. Step through transitions (Idle -> Starting -> Running).
  6. Inspect Variables panel and inline values for Status.State and Ramp.

Step 4: Understand Configuration Relationship

Read src/config.st and map the hierarchy:

  • CONFIGURATION defines deployment root.
  • TASK defines scan interval/priority.
  • PROGRAM ... WITH TASK binds logic execution.
  • VAR_CONFIG binds symbols to %I/%Q addresses.

This is the runtime wiring contract for your typed logic model.

Step 5: Guided Change Exercise

  1. In src/fb_pump.st, change:
  2. RampTime : TIME := T#1s; -> T#2s
  3. Re-run debug.
  4. Observe longer time spent in Starting before Running.

Troubleshooting

  • If F5 fails:
  • confirm trust-debug path in .vscode/settings.json.
  • If no cross-file symbols:
  • confirm workspace root is examples/plant_demo.
  • If no runtime change on input toggles:
  • confirm correct %IX/%IW addresses from src/config.st.

OpenOT Multi-PROGRAM Logging

This project demonstrates the truST OpenOT authoring path with two PROGRAM blocks publishing into one OpenOT shared-memory ring.

  • Filler tags a message, state enum, and level value.
  • Quality tags a message, integer value, audited setpoint value, and alarm.
  • The source has no logging calls, no Op :=, and no user-visible OpenOT ids.
  • truST generates Filler.OotProducer and Quality.OotProducer.
  • runtime.toml drains those generated producers with producer_instances.
  • trust-lsp.toml pulls in the sibling OpenOT ST producer sources from open-ot-ref/st/iec61131.

Build

From the repository root:

trust-runtime build --project examples/openot_multi_program --sources src

This generates program.stbc in the example directory.

Run

trust-runtime run --project examples/openot_multi_program

The runtime publishes OpenOT records to openot-multi-program.shm using:

[runtime.openot]
enabled = true
source = "st-fb"
producer_instances = ["Filler.OotProducer", "Quality.OotProducer"]

The runtime is still the single writer to the ring. The per-program ST producers are drained sequentially, so consumers separate the stream by sourceId and per-source seq.

The sibling OpenOT workbench keeps the reference copy of this source shape in open-ot-ref/examples/multi-program/.