docs(ab): hw4 evidence fix round 1 - bit-write gap provenance, README/CLI/fixture docs, libplctag-deletion gap
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
+3
-3
@@ -77,9 +77,9 @@ their flag values to the already-shipped driver.
|
||||
non-empty CIP routing path before forwarding to the PCCC dispatcher.
|
||||
Pass `--gateway "ab://127.0.0.1:44818/1,0"` against the Docker
|
||||
fixture; real SLC / MicroLogix / PLC-5 hardware accepts an empty
|
||||
path (`ab://host:44818/`). Bit-file writes (`B3:0/5`) still surface
|
||||
`0x803D0000` against ab_server — route operator-critical bit writes
|
||||
to real hardware until upstream fixes this.
|
||||
path (`ab://host:44818/`). Bit-file writes (`B3:0/5`) pass against
|
||||
ab_server SLC500/MicroLogix on both transports (the old `0x803D0000` no longer
|
||||
reproduces; native PLC-5 refuses all writes with the same code, #571).
|
||||
- **S7 PUT/GET communication** must be enabled in TIA Portal for any
|
||||
S7-1200/1500. See [Driver.S7.Cli.md](Driver.S7.Cli.md).
|
||||
- **TwinCAT AMS router** must be reachable (local XAR, standalone Router
|
||||
|
||||
@@ -243,7 +243,8 @@ The driver has two interchangeable wire transports, selected by one `DriverConfi
|
||||
Good). Still ab_server-only: array, STRING and UDT-member writes and fragmented writes. Mixed STRING/array/scalar
|
||||
Multiple Service Packet reads (#582) are proven on the press (one 5-read MSP, values equal to single reads). Results:
|
||||
[native-ab-transport-gate-results](../plans/2026-10-07-native-ab-transport-gate-results.md).
|
||||
- **libplctag cannot be deleted** until a bench controller allows write verification.
|
||||
- **libplctag cannot be deleted yet.** Scalar native writes are proven on a CompactLogix (2026-10-09); what remains is #567
|
||||
(fragmented wide-struct writes), array/STRING/UDT-member writes on hardware, and AbLegacy native (simulator-only, no PCCC hardware).
|
||||
- ⚠️ RESIDUAL (#567): wide-struct **fragmented writes** (8-byte alignment) are unit-tested only. Production
|
||||
presses are read-only and there is no bench controller, so this cannot be proven; it stays open until a
|
||||
bench controller exists.
|
||||
|
||||
@@ -11,8 +11,8 @@ for N-file (Int16), F-file (Float32), and L-file (Int32) reads across all
|
||||
three families when `AB_LEGACY_CIP_PATH=1,0` (the default). The earlier
|
||||
`BadCommunicationError` was traced to `ab_server` requiring a non-empty CIP
|
||||
routing path before forwarding to the PCCC dispatcher — the `/1,0` workaround
|
||||
resolves it (see `Docker/README.md §Known limitations`). Residual gap: bit-file
|
||||
writes (`B3:0/5`) still surface `0x803D0000` against `ab_server`. Unit tests
|
||||
resolves it (see `Docker/README.md §Known limitations`). The old bit-file write
|
||||
gap (`B3:0/5` giving `0x803D0000`) no longer reproduces (2026-10-09, `AbLegacyBitWriteTests`). Unit tests
|
||||
via `FakeAbLegacyTag` carry full contract coverage for all paths.
|
||||
|
||||
## What the fixture is
|
||||
@@ -105,12 +105,10 @@ cover the common ones but uncommon ones (`R` counters, `S` status files,
|
||||
|
||||
## Follow-up candidates
|
||||
|
||||
1. **Close residual ab_server bit-file write gap** — N (Int16), F (Float32),
|
||||
and L (Int32) files round-trip cleanly across SLC500 / MicroLogix / PLC-5
|
||||
modes with the `/1,0` cip-path workaround in place. Remaining gap: bit-file
|
||||
writes (`B3:0/5`) surface `0x803D0000` against `ab_server --plc=SLC500`.
|
||||
Contributing a patch to `libplctag/libplctag` to close this would remove
|
||||
the last Docker-vs-hardware divergence for bit writes.
|
||||
1. **(Closed, 2026-10-09) ab_server bit-file write gap** — N, F and L files
|
||||
round-trip with the `/1,0` workaround, and `B3:0/5` bit writes now pass on
|
||||
SLC500/MicroLogix (both transports; `AbLegacyBitWriteTests`). The May 2026
|
||||
`0x803D0000` does not reproduce; its cause is undetermined.
|
||||
2. **Rockwell RSEmulate 500 golden-box tier** — Rockwell's real emulator
|
||||
for SLC/MicroLogix/PLC-5. Would close UDT-equivalent (integer-file
|
||||
indirection), timer/counter decomposition, and real ladder execution
|
||||
|
||||
@@ -219,7 +219,7 @@ Everything below is against the `ab_server` simulator; no real PCCC controller h
|
||||
| F-file read (`F8`) | one capture, `slc500-read-f8` (codec parity only; no native F write on a wire) |
|
||||
| S (incl. the default probe `S:0`), B, T, C, R, L, ST, A, O, I | **none** — encoded from the PCCC file-type table |
|
||||
| MicroLogix function files (RTC/HSC/...), PLC-5 octal I/O | **none** — parsed only; native refuses function files as Unsupported |
|
||||
| Bit-within-word write (`B3:0/5`) | `ab_server` SLC500 + MicroLogix, both transports (`AbLegacyBitWriteTests`): the driver RMWs the parent word, only the addressed bit changes. PLC-5 native refuses it (`BadNotSupported`, #571) |
|
||||
| Bit-within-word write (`B3:0/5`) | `ab_server` SLC500 + MicroLogix, both transports (`AbLegacyBitWriteTests`): the driver RMWs the parent word, only the addressed bit changes (the parent-word read-modify-write is not atomic against ladder writes to the same word). PLC-5 native refuses it (`BadNotSupported`, #571) |
|
||||
| Indirect addressing (`N7:[N7:0]`) | `ab_server` N-file, both transports (#646) - resolved by the driver, the transport sees the composed address |
|
||||
| T/C/R sub-elements (`.PRE`/`.ACC`/`.LEN`/`.POS`), 6-byte T/C/R element layout | **none** |
|
||||
|
||||
|
||||
@@ -539,23 +539,23 @@ pages** (controller scope 8 pages, then each of the 15 programs, up to 6 pages f
|
||||
alike; this is evidence only, no code changed.
|
||||
- One empty page (`Program:Auxiliary`, 0 entries) was observed and handled.
|
||||
|
||||
### ab_server PCCC bit-file write (`B3:0/5`): not an ab_server gap (no patch needed)
|
||||
### ab_server PCCC bit-file write (`B3:0/5`): the documented gap does not reproduce (no patch)
|
||||
|
||||
The reported failure `0x803D0000` is `BadNotSupported`. Reproduced with new `AbLegacyBitWriteTests`
|
||||
(writes `B3:0` = 0x0A0A, sets bit 5, clears bit 3, asserts the whole word each time so neighbour bits are proven preserved),
|
||||
local ab_server (libplctag v2.7.0 + patches 0001/0002, built in OrbStack), `AB_LEGACY_ENDPOINT` pinned to a lane-local port:
|
||||
Provenance: `AbLegacy.IntegrationTests/Docker/README.md` ("Bit-file writes on ab_server", May 2026, libplctag + `--plc=SLC500`,
|
||||
before the native transport) recorded `B3:0/5` -> `0x803D0000`. New `AbLegacyBitWriteTests` (writes `B3:0` = 0x0A0A, sets
|
||||
bit 5, clears bit 3, asserts the whole word each time so neighbour bits are proven preserved) against local ab_server
|
||||
(libplctag v2.7.0 + patches 0001/0002, OrbStack, `AB_LEGACY_ENDPOINT` pinned to a lane-local port):
|
||||
|
||||
| Family | Libplctag | Native |
|
||||
|---|---|---|
|
||||
| SLC500 | pass | pass |
|
||||
| MicroLogix | pass | pass |
|
||||
| PLC-5 | pass | `BadNotSupported` (0x803D0000), by design |
|
||||
|
||||
- The driver does a per-parent-word read-modify-write (typed read, then typed write of the word), never a masked CMD 0x0F/FNC
|
||||
0xAB write, so the bit write needs nothing ab_server lacks. (ab_server does implement FNC 0xAB, `handle_slc_rmw_request`, for
|
||||
16-bit elements; the driver simply does not use it.)
|
||||
- The 0x803D0000 is the **native PLC-5 write refusal** (#571, `NativeAbLegacyTagRuntime.WriteRefusal`: all PLC-5 writes are
|
||||
refused before the wire). The test pins it for PLC-5 + Native and requires success everywhere else. Because nothing was broken,
|
||||
there is no fix to revert for a red/green proof; the PLC-5 expectation was the part that failed first (red) when the test
|
||||
wrongly assumed success, which shows the assertions discriminate. No Dockerfile or patch change.
|
||||
| PLC-5 | pass | `BadNotSupported` (0x803D0000) |
|
||||
|
||||
- **Finding:** the originally documented gap does not reproduce on the current fixture and driver; the cause of the original
|
||||
failure is undetermined. No ab_server patch or Dockerfile change is needed. The driver does a per-parent-word read-modify-write
|
||||
(typed read, typed write of the word), not a masked FNC 0xAB write (ab_server does implement 0xAB for 16-bit elements).
|
||||
- The PLC-5 native `0x803D0000` is a **separate, intended** behaviour that merely shares the status code: all native PLC-5
|
||||
writes are refused before the wire (#571, `NativeAbLegacyTagRuntime.WriteRefusal`). The test pins it. It is not the original
|
||||
observation.
|
||||
- No fix, so no revert-to-red proof; the test would fail if the word RMW clobbered neighbour bits.
|
||||
|
||||
+1
@@ -193,6 +193,7 @@ public sealed class EvidenceTests
|
||||
$"max={(ids.Count > 0 ? ids.Max() : 0)} more={more} ascending={strictly} ids=[{sample}]");
|
||||
}
|
||||
Log($"Non-ascending pages: {nonAscending}");
|
||||
Log(nonAscending == 0 ? "RESULT: every listing page strictly ascending." : $"RESULT: {nonAscending} NON-ASCENDING page(s) observed.");
|
||||
pages.ShouldNotBeEmpty();
|
||||
opens.ShouldBe(1);
|
||||
}
|
||||
|
||||
@@ -121,11 +121,17 @@ trip cleanly across SLC500, MicroLogix, and PLC-5 modes.
|
||||
|
||||
### Bit-file writes on ab_server
|
||||
|
||||
`B3:0/5`-style bit-in-boolean writes currently surface `0x803D0000`
|
||||
against `ab_server --plc=SLC500`; bit reads work. Non-blocking for the
|
||||
smoke suite (which targets N-file Int16 + F-file float reads), but
|
||||
bit-write fidelity isn't simulator-verified — route operator-critical
|
||||
bit writes to real hardware or RSEmulate 500 until upstream resolves.
|
||||
Originally (May 2026, libplctag only, before the native transport) a `B3:0/5`
|
||||
bit write surfaced `0x803D0000` against `ab_server --plc=SLC500`. **That does
|
||||
not reproduce any more** (2026-10-09): `AbLegacyBitWriteTests` writes `B3:0`,
|
||||
sets bit 5 and clears bit 3 and asserts the whole word each time, and passes
|
||||
on SLC500 and MicroLogix on both libplctag and native, and on PLC-5 with
|
||||
libplctag. The cause of the original failure was never determined (the
|
||||
driver's parent-word read-modify-write and ab_server's PCCC handlers are
|
||||
both unchanged in shape, so an older libplctag/driver path is the likely
|
||||
difference). PLC-5 on the native transport returns `0x803D0000`
|
||||
(`BadNotSupported`) for a different reason: all native PLC-5 writes are
|
||||
refused before the wire (#571); the test pins that.
|
||||
|
||||
### Other known gaps (unchanged from ab_server)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user