Runtime readiness and persistent-image qualification¶
A restart command being accepted does not prove the runtime is usable. The readiness runner checks system RUN, PLC RUN and an advancing application counter. When configured, it also opens an authenticated OPC UA session with pinned server certificate and checks the PLC device error status. Two consecutive complete probes must pass. Each attempt runs in a fresh process with a bounded deadline; no route, service or application state is changed by the monitor.
On the dedicated bench, an orderly Windows reboot recovered without refreshing Secure ADS routes. Complete Example/OPC UA readiness took about 197 seconds from the start of monitoring (which began after the reboot command). This is one observed reboot, not a universal startup bound or proof that the earlier TLS failure cannot recur. Use the report's failed stage to distinguish ADS, cyclic execution and OPC UA startup.
Read-only readiness¶
Create a local JSON config, for example artifacts/readiness.json:
{
"target": "172.18.236.100.1.1",
"fixture": "Example",
"port": 851,
"ads_dll_directory": "C:/Program Files (x86)/Beckhoff/TwinCAT/Common64"
}
Use Simulation and port 854 for the unmapped lifecycle fixture. Use
Testing and port 853 to check that the TcUnit task is advancing before
collecting its ADS results. This readiness check is read-only and never reboots
or reactivates the target.
Optional opcua configuration requires endpoint, application_uri, certificate,
key, server_certificate, user, password_env and namespace. Certificates
must already be trusted. Supply the password through the named process environment
variable; do not include it in the config or commit it.
python scripts/wait_runtime_ready.py --config artifacts/readiness.json `
--output artifacts/readiness-result.json --timeout 300
Example and Simulation activation scripts also use this monitor for cyclic readiness. Their default activation check does not include OPC UA; supply the optional configuration when that layer is required.
The output path must be new. Exit zero means all requested layers passed twice; nonzero means readiness was not established within the budget. Reports retain failed stages and numeric ADS errors, but not arbitrary server error text or credentials. A hung probe is terminated within its attempt budget.
Restart without deployment¶
On an authorized dedicated target:
powershell.exe -NoProfile -File scripts/restart_runtime.ps1 `
-Target 172.18.236.100.1.1 -Solution TwinCAT/TcForge.Example.sln `
-Output artifacts/restart-dispatch.json
This uses StartRestartTwinCAT in an owned XAE session, preserves project files,
and serializes access with the other engineering scripts. It does not build,
activate a configuration, download PLC code or generate a boot project. Its
receipt deliberately leaves RuntimeVerified false. Run the readiness check
separately. See Beckhoff's
Automation Interface.
Controlled persistent images¶
scripts/verify_persistent_images.py is restricted to the unmapped Simulation
fixture on port 854. Install the Python bench extra on the engineering PC. The
runner requires an existing route, SSH account and independently verified SHA256
hex fingerprint of the SSH host public key.
Its local JSON config requires:
dedicated_unmapped_bench: explicittrueauthorization for this fixture.target,port(854),host, andsolution(Simulation solution path).boot_directory: the target's absolute Windows path ending inBoot/Plc.ssh_user,ssh_password_env,ssh_sha256, andads_dll_directory.corrupt_recovery: explicitlyreinitializeorbackupfor the qualified target/configuration. The tested 3.1.4026.17 bench reinitializes after the malformed-current-file case; backup-only loading is tested separately.
python scripts/verify_persistent_images.py --config artifacts/images-config.json `
--output artifacts/images-run
The runner seeds known persistent state, observes CONFIG before touching files,
backs up Port_854.bootdata and Port_854.bootdata-old, and verifies every file
write by readback. CONFIG control runs over authenticated SSH against the
bench-local ADS router, and verifies that the local AMS identity matches the
requested target. The Windows helper uses C:/TwinCAT/Common64/TcAdsDll.dll.
The helper is copied to a uniquely named Windows temporary file and removed
after execution; its execution-policy override applies only to that PowerShell
process. No machine execution policy or certificate trust is changed.
This avoids relying on a network ADS session while that session is being disrupted
by CONFIG. It exercises missing images, a backup-only image and a corrupt
current image with a valid backup. A corrupt current file is not assumed to have
the same recovery behavior as an absent current file: Beckhoff documents backup
loading when the current file is absent in the
persistent-data settings.
The configured expectation is strict: reinitialization requires both image flags
clear, default markers/history and inhibited outputs; backup recovery requires
the backup flag, seeded markers/history and inhibited outputs. It never accepts
an arbitrary outcome just because the PLC started. XAE restarts the existing configuration, and
readiness is checked before reading fixture state. Each case must prove inhibited
outputs and the expected image flags/markers. Cleanup restores the original bytes,
checks restored state and explicitly clears outputs. A failed cleanup fails the
run; retain its local backups for recovery. Use --cases missing,
--cases backup_only, or --cases corrupt_current_with_backup for a targeted
rerun; the report lists requested cases and does not imply unselected cases passed.
The corruption fixture replaces the current file with a short malformed image. It does not exhaust every possible partial-write or byte-corruption pattern. These controlled file cases do not simulate electrical power removal or prove storage durability. Do not run them against a mapped or production application.