docs(drivers): B/I/O + BOOL-within-word bit writes (RMW)
This commit is contained in:
@@ -40,7 +40,7 @@ scope.
|
||||
|------------|---------------------------|-------|
|
||||
| `ITagDiscovery` | `DiscoverAsync` | Emits pre-declared tags under per-device folders. Tags are single-element today (`IsArray` hard-wired false); multi-element file ranges are a tracked follow-up. |
|
||||
| `IReadable` | `ReadAsync` | Per-tag reads serialized per cached runtime under a lock (a libplctag `Tag` handle is not concurrency-safe across the server read path + poll loop). |
|
||||
| `IWritable` | `WriteAsync` | Bit-within-word writes (N-file `N7:0/3`, B-file bits) do a per-parent-word read-modify-write under a lock. Non-writable tags return `BadNotWritable`. |
|
||||
| `IWritable` | `WriteAsync` | Bit-within-word writes (N/L-file `N7:0/3`, B-file `B3:0/0`, and I/O image files `I:0/0`/`O:1/2`) do a per-parent-word read-modify-write under a lock. An Input-image (`I`) write is forwarded to the PLC and may be rejected by the device (the device drives the input image from physical inputs); the driver surfaces the device's real PCCC status in that case. Non-writable tags return `BadNotWritable`. |
|
||||
| `ISubscribable` | `SubscribeAsync` driven by the shared `PollGroupEngine` | No push model — subscriptions become polling groups. |
|
||||
| `IHostConnectivityProbe` | `ProbeLoopAsync` + `GetHostStatuses` | One probe loop per device reading `Probe.ProbeAddress`; transitions log Warning (down) / Information (recover). |
|
||||
| `IPerCallHostResolver` | `ResolveHost` | Routes each call to the tag's `DeviceHostAddress`; unknown references fall back to the first device, never throwing (per the interface contract). |
|
||||
@@ -75,6 +75,16 @@ PCCC structural rules — bit-addressing only on 16/32-bit element files,
|
||||
sub-elements only on T/C/R files, no file number on I/O/S — rejecting malformed
|
||||
addresses before they reach libplctag.
|
||||
|
||||
**Bit-within-word writes** — B-file (`B3:0/0`), I/O image (`I:0/0`, `O:1/2`),
|
||||
N-file (`N7:0/3`), and L-file bit addresses all use the same parent-word
|
||||
read-modify-write (RMW) path: the driver reads the parent word, flips the target
|
||||
bit, and writes the word back, under a per-parent lock. The lock serialises the
|
||||
driver's own concurrent bit-writers against the same word, but cannot guard
|
||||
against the PLC program writing that word between the driver's read and write —
|
||||
this is an inherent limitation of any software-level RMW. Input-image (`I`) bit
|
||||
writes are forwarded to the PLC as-is; the device drives the input image from
|
||||
physical inputs and may reject the write.
|
||||
|
||||
## Configuration
|
||||
|
||||
`AbLegacyDriverOptions` (`Driver.AbLegacy.Contracts/AbLegacyDriverOptions.cs`)
|
||||
|
||||
@@ -62,6 +62,14 @@ mirrors IEC 61131-3 structured-text identifiers: global-variable-list
|
||||
(`Motor1.Status.Running`), array subscripts (`Data[5]`, `Matrix[1,2]`), and
|
||||
bit-access (`Flags.0`).
|
||||
|
||||
**BOOL-within-word writes** — writing a bit-access path (e.g. `MAIN.Flags.3`)
|
||||
is a driver-level parent-word read-modify-write: the driver reads the parent
|
||||
word as `UDInt`, flips the target bit, and writes the word back, under a
|
||||
per-parent lock. The lock serialises the driver's own concurrent bit-writers
|
||||
against the same word, but cannot guard against the PLC program writing that
|
||||
word between the driver's read and write — this is an inherent limitation of
|
||||
any software-level RMW.
|
||||
|
||||
## Tag discovery
|
||||
|
||||
`DiscoverAsync` always emits the pre-declared `Tags` as the authoritative config
|
||||
@@ -79,7 +87,7 @@ discovery.
|
||||
| Capability | Path | Notes |
|
||||
|------------|------|-------|
|
||||
| `IReadable` | `ReadAsync` → ADS `ReadValueAsync` | Per-device client, lazily connected and serialized per device |
|
||||
| `IWritable` | `WriteAsync` → ADS `WriteValueAsync` | Read-only tags return `BadNotWritable` |
|
||||
| `IWritable` | `WriteAsync` → ADS `WriteValueAsync` | BOOL-within-word writes (e.g. `MAIN.Flags.3`) use a driver-level parent-word read-modify-write (read as UDInt, flip bit, write back) under a per-parent lock. Read-only tags return `BadNotWritable`. |
|
||||
| `ITagDiscovery` | `DiscoverAsync` | Pre-declared tags + opt-in controller symbol browse |
|
||||
| `ISubscribable` | native ADS notifications (default), poll fallback | `UseNativeNotifications=true` registers device notifications so the PLC pushes changes; `false` uses the shared `PollGroupEngine` |
|
||||
| `IHostConnectivityProbe` | per-device probe loop | One `HostConnectivityStatus` per configured device; `Running`/`Stopped` transitions raise `OnHostStatusChanged` |
|
||||
|
||||
Reference in New Issue
Block a user