Auto: abcip-3.1 — configurable CIP connection size per device
Closes #235
This commit is contained in:
153
docs/drivers/AbCip-Performance.md
Normal file
153
docs/drivers/AbCip-Performance.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# AB CIP — Performance knobs
|
||||
|
||||
Phase 3 of the AB CIP driver plan introduces a small set of operator-tunable
|
||||
performance knobs that change how the driver talks to the controller without
|
||||
altering the address space or per-tag semantics. They consolidate decisions
|
||||
that Kepware exposes as a slider / advanced page so deployments running into
|
||||
high-latency PLCs, narrow-CPU CompactLogix parts, or legacy ControlLogix
|
||||
firmware have an explicit lever to pull.
|
||||
|
||||
This document is the home for those knobs as PRs land. PR abcip-3.1 ships the
|
||||
first knob: per-device **CIP Connection Size**.
|
||||
|
||||
## Connection Size
|
||||
|
||||
### What it is
|
||||
|
||||
CIP Connection Size — the byte ceiling on a single Forward Open response
|
||||
fragment, set during the EtherNet/IP Forward Open handshake. Larger
|
||||
connection sizes pack more tags into a single CIP RTT (higher request-packing
|
||||
density, fewer round-trips for the same scan list); smaller connection sizes
|
||||
stay compatible with legacy or narrow-buffer firmware that rejects oversized
|
||||
Forward Open requests.
|
||||
|
||||
### Family defaults
|
||||
|
||||
The driver picks a Connection Size from the per-family profile when the
|
||||
device-level override is unset:
|
||||
|
||||
| Family | Default | Rationale |
|
||||
|---|---:|---|
|
||||
| `ControlLogix` | `4002` | Large Forward Open — FW20+ |
|
||||
| `GuardLogix` | `4002` | Same wire protocol as ControlLogix |
|
||||
| `CompactLogix` | `504` | 5069-L1/L2/L3 narrow-buffer parts (5370 family) |
|
||||
| `Micro800` | `488` | Hard cap on Micro800 firmware |
|
||||
|
||||
These map straight to libplctag's `connection_size` attribute and match the
|
||||
defaults Kepware uses out of the box for the same families.
|
||||
|
||||
### Override knob
|
||||
|
||||
`AbCipDeviceOptions.ConnectionSize` (`int?`, default `null`) overrides the
|
||||
family default for one device. Bind it through driver config JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"Devices": [
|
||||
{
|
||||
"HostAddress": "ab://10.0.0.5/1,0",
|
||||
"PlcFamily": "ControlLogix",
|
||||
"ConnectionSize": 504
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The override threads through every libplctag handle the driver creates for
|
||||
that device — read tags, write tags, probe tags, UDT-template reads, the
|
||||
`@tags` walker, and BOOL-in-DINT parent runtimes. There is no per-tag
|
||||
override; one Connection Size applies to the whole controller (matches CIP
|
||||
session semantics).
|
||||
|
||||
### Valid range
|
||||
|
||||
`[500..4002]` bytes. This matches the slider Kepware exposes for the same
|
||||
family. Values outside the range fail driver `InitializeAsync` with an
|
||||
`InvalidOperationException` — there's no silent clamp; misconfigured devices
|
||||
fail loudly so operators see the problem at deploy time.
|
||||
|
||||
| Value | Behaviour |
|
||||
|---|---|
|
||||
| `null` | Use family default (4002 / 504 / 488) |
|
||||
| `499` or below | Driver init fault — out-of-range |
|
||||
| `500..4002` | Threaded through to libplctag |
|
||||
| `4003` or above | Driver init fault — out-of-range |
|
||||
|
||||
### Legacy-firmware caveat
|
||||
|
||||
ControlLogix firmware **v19 and earlier** caps the CIP buffer at **504
|
||||
bytes** — Connection Sizes above that cause the controller to reject the
|
||||
Forward Open with CIP error 0x01/0x113. The 5069-L1/L2/L3 CompactLogix narrow
|
||||
parts are subject to the same cap.
|
||||
|
||||
The driver emits a warning via `AbCipDriverOptions.OnWarning` when the
|
||||
configured Connection Size **exceeds 511** *and* the device's family profile
|
||||
default is also at-or-below the legacy cap (i.e. CompactLogix with default
|
||||
504, or Micro800 with default 488). Production hosting should wire
|
||||
`OnWarning` to the application logger; the unit tests (`AbCipConnectionSizeTests`)
|
||||
collect into a list to assert which warnings fired.
|
||||
|
||||
The warning fires once per device at `InitializeAsync`. It does not block
|
||||
initialisation — operators may need the override anyway when running newer
|
||||
CompactLogix firmware that does support the larger Forward Open. The
|
||||
controller will reject the connection at runtime if it can't honour the size,
|
||||
and that surfaces through the standard `IHostConnectivityProbe` channel.
|
||||
|
||||
### Performance trade-off
|
||||
|
||||
| Larger Connection Size | Smaller Connection Size |
|
||||
|---|---|
|
||||
| More tags per CIP RTT — higher throughput | Compatible with legacy / narrow firmware |
|
||||
| Bigger buffers held by libplctag native (RSS impact) | Lower memory footprint |
|
||||
| Forward Open rejected on FW19- ControlLogix | Always works (assuming ≥500) |
|
||||
| Required for high-density scan lists | Forces more round-trips — higher latency |
|
||||
|
||||
For most FW20+ ControlLogix shops, the default `4002` is correct and the
|
||||
override is unnecessary. The override is mainly useful when:
|
||||
|
||||
1. **Migrating off Kepware** with a controller-specific slider value already
|
||||
tuned in production — set Connection Size to match.
|
||||
2. **Mixed-firmware fleets** where some controllers are still on FW19 — set
|
||||
the legacy controllers explicitly to `504`.
|
||||
3. **CompactLogix L1/L2/L3** running newer firmware that supports a larger
|
||||
Forward Open than the family-default 504 — bump the override up.
|
||||
4. **Micro800** never goes above `488`; the override is for documentation /
|
||||
discoverability rather than capability change.
|
||||
|
||||
### libplctag wrapper limitation
|
||||
|
||||
The libplctag .NET wrapper (1.5.x) does not expose `connection_size` as a
|
||||
public `Tag` property. The driver propagates the value via reflection on the
|
||||
wrapper's internal `NativeTagWrapper.SetIntAttribute("connection_size", N)`
|
||||
after `InitializeAsync` — equivalent to libplctag's
|
||||
`plc_tag_set_int_attribute`. Because libplctag native parses
|
||||
`connection_size` only at create time, this is **best-effort** until either:
|
||||
|
||||
- the libplctag .NET wrapper exposes `ConnectionSize` directly (planned in
|
||||
the upstream backlog), in which case the reflection no-ops cleanly, or
|
||||
- libplctag native gains post-create hot-update for `connection_size`, in
|
||||
which case the call lands as intended.
|
||||
|
||||
In the meantime the value is correctly stored on `DeviceState.ConnectionSize`
|
||||
+ surfaces in every `AbCipTagCreateParams` the driver builds, so the override
|
||||
is observable end-to-end through the public driver surface and unit tests
|
||||
even if the underlying wrapper isn't yet honouring it on the wire.
|
||||
|
||||
Operators who need *guaranteed* Connection Size enforcement against FW19
|
||||
controllers today can pin `libplctag` to a wrapper version that exposes
|
||||
`ConnectionSize` once one is available, or run a libplctag native build
|
||||
patched for runtime updates. Both paths are tracked in the AB CIP plan.
|
||||
|
||||
### See also
|
||||
|
||||
- [`docs/Driver.AbCip.Cli.md`](../Driver.AbCip.Cli.md) — AB CIP CLI uses the
|
||||
family default ConnectionSize on each invocation; per-device overrides only
|
||||
apply through the driver's device-config JSON, not the CLI's command-line.
|
||||
- [`docs/drivers/AbServer-Test-Fixture.md`](AbServer-Test-Fixture.md) §5 —
|
||||
ab_server simulator does not enforce the narrow CompactLogix cap, so
|
||||
Connection Size correctness is verified by unit tests + Emulate-rig live
|
||||
smokes only.
|
||||
- [`PlcFamilies/AbCipPlcFamilyProfile.cs`](../../src/ZB.MOM.WW.OtOpcUa.Driver.AbCip/PlcFamilies/AbCipPlcFamilyProfile.cs) —
|
||||
per-family default values.
|
||||
- [`AbCipConnectionSize`](../../src/ZB.MOM.WW.OtOpcUa.Driver.AbCip/AbCipConnectionSize.cs) —
|
||||
range bounds + legacy-firmware threshold constants.
|
||||
Reference in New Issue
Block a user