154 lines
6.9 KiB
Markdown
154 lines
6.9 KiB
Markdown
# 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.
|