docs(s7): wide-type/Timer-Counter support — CLI help + driver-specs + S7 driver doc
Drop the "not yet implemented / BadNotSupported" stale note from all three S7 CLI --type option descriptions (ReadCommand, WriteCommand, SubscribeCommand) and replace with accurate help listing the full supported type set, byte-anchored addressing for wide types, and Timer/Counter read-only status. docs/v2/driver-specs.md §5: add Supported Data Types table, Byte-Anchored Addressing table (DBB/MB/IB/QB + examples), Timer/Counter read section with the Counter-BCD known-limitation, and Deferrals list. docs/drivers/S7.md: expand Data types to a full table, add "Wide types & Timer/Counter" section (byte-anchored addressing, Timer/Counter read-only, Counter BCD known-limitation, deferrals), update Address forms table and 1-D array Deferrals note.
This commit is contained in:
+64
-4
@@ -395,13 +395,73 @@ Pure managed .NET, MIT license. No native dependencies.
|
||||
|
||||
| Area | Address Syntax | Area Code | Examples |
|
||||
|------|---------------|-----------|----------|
|
||||
| Data Block | `DB{n}.DB{X\|B\|W\|D}{offset}[.bit]` | 0x84 | `DB1.DBX0.0`, `DB1.DBW0`, `DB1.DBD4` |
|
||||
| Merkers | `M{B\|W\|D}{offset}` or `M{offset}.{bit}` | 0x83 | `M0.0`, `MW0`, `MD4` |
|
||||
| Inputs | `I{B\|W\|D}{offset}` or `I{offset}.{bit}` | 0x81 | `I0.0`, `IW0`, `ID0` |
|
||||
| Outputs | `Q{B\|W\|D}{offset}` or `Q{offset}.{bit}` | 0x82 | `Q0.0`, `QW0`, `QD0` |
|
||||
| Data Block | `DB{n}.DB{X\|B\|W\|D}{offset}[.bit]` | 0x84 | `DB1.DBX0.0`, `DB1.DBW0`, `DB1.DBD4`, `DB1.DBB8` |
|
||||
| Merkers | `M{B\|W\|D}{offset}` or `M{offset}.{bit}` | 0x83 | `M0.0`, `MW0`, `MD4`, `MB4` |
|
||||
| Inputs | `I{B\|W\|D}{offset}` or `I{offset}.{bit}` | 0x81 | `I0.0`, `IW0`, `ID0`, `IB0` |
|
||||
| Outputs | `Q{B\|W\|D}{offset}` or `Q{offset}.{bit}` | 0x82 | `Q0.0`, `QW0`, `QD0`, `QB0` |
|
||||
| Timers | `T{n}` | 0x1D | `T0`, `T15` |
|
||||
| Counters | `C{n}` | 0x1C | `C0`, `C10` |
|
||||
|
||||
### Supported Data Types
|
||||
|
||||
| DataType | S7 Type | Width | Read | Write | Notes |
|
||||
|----------|---------|-------|------|-------|-------|
|
||||
| `Bool` | BOOL | 1 bit | yes | yes | |
|
||||
| `Byte` | BYTE | 1 byte | yes | yes | |
|
||||
| `Int16` | INT | 2 bytes | yes | yes | |
|
||||
| `UInt16` | WORD | 2 bytes | yes | yes | |
|
||||
| `Int32` | DINT | 4 bytes | yes | yes | |
|
||||
| `UInt32` | DWORD | 4 bytes | yes | yes | |
|
||||
| `Float32` | REAL | 4 bytes | yes | yes | |
|
||||
| `Int64` | LINT | 8 bytes | yes | yes | Byte-anchored — see below |
|
||||
| `UInt64` | ULINT/LWORD | 8 bytes | yes | yes | Byte-anchored — see below |
|
||||
| `Float64` | LREAL | 8 bytes | yes | yes | Byte-anchored — see below |
|
||||
| `String` | STRING | `StringLength + 2` bytes | yes | yes | Byte-anchored; default `StringLength`=254 |
|
||||
| `DateTime` | DATE_AND_TIME | 8 bytes | yes | yes | Byte-anchored — see below |
|
||||
| Timer | TIME | — | yes | **no** | `T{n}` address only; DataType must be `Float64`; value = seconds |
|
||||
| Counter | COUNTER | — | yes | **no** | `C{n}` address only; DataType must be `Int32`; value = raw word |
|
||||
|
||||
### Wide / Structured Types — Byte-Anchored Addressing
|
||||
|
||||
Wide types (`Int64`, `UInt64`, `Float64`/LReal, `String`, `DateTime`) are **byte-anchored**: the
|
||||
address must use the `B` suffix to specify the start byte; the driver reads the
|
||||
correct number of bytes based on the DataType.
|
||||
|
||||
| DataType | Required address form | Example |
|
||||
|----------|-----------------------|---------|
|
||||
| `Int64` | `DB{n}.DBB{offset}` / `MB{offset}` / `IB{offset}` / `QB{offset}` | `DB1.DBB8` → LINT at bytes 8–15 |
|
||||
| `UInt64` | same | `DB2.DBB16` → ULINT at bytes 16–23 |
|
||||
| `Float64` | same | `DB1.DBB8` → LREAL at bytes 8–15 |
|
||||
| `DateTime` | same | `DB3.DBB0` → DATE_AND_TIME at bytes 0–7 |
|
||||
| `String` | same | `DB4.DBB0` DataType=String, StringLength=40 → reads 42 bytes |
|
||||
|
||||
Using a `W` (word) or `D` (dword) suffix with a wide DataType produces an address parse
|
||||
error at `InitializeAsync`.
|
||||
|
||||
### Timer / Counter Read
|
||||
|
||||
**Timer (`T{n}`)** — reads the timer's current value as elapsed **seconds** (double). The OPC UA
|
||||
node DataType is `Float64`. Timers are **read-only** this phase; writes return `BadNotWritable`.
|
||||
|
||||
**Counter (`C{n}`)** — reads the counter current value as a raw count (`int`). The OPC UA node
|
||||
DataType is `Int32`. Counters are **read-only** this phase; writes return `BadNotWritable`.
|
||||
|
||||
> **Counter known-limitation**: `S7.Net`'s `Counter.FromByteArray` returns the raw big-endian
|
||||
> word without BCD decode. On **classic S7-300/400** the C-area word is BCD-encoded (0–999),
|
||||
> so the surfaced value can differ from the actual count on that hardware. S7-1200/1500 use
|
||||
> IEC/DB counters (plain integers) where the raw word is correct. BCD reinterpretation for
|
||||
> legacy C-area is a live-hardware-gated follow-up.
|
||||
|
||||
### Deferrals (not yet implemented)
|
||||
|
||||
The following are explicitly deferred and will return `BadNotSupported` or a config error if attempted:
|
||||
|
||||
- **Wide-type arrays** — array tags (`isArray: true`) with element types `Int64`, `UInt64`,
|
||||
`Float64`, `String`, or `DateTime`.
|
||||
- **`S7WString`** (2-byte characters; distinct from `STRING`).
|
||||
- **`DTL` / `DateTimeLong`** (12-byte Siemens date-and-time-long).
|
||||
- **Timer / Counter writes** — surfaced as `BadNotWritable` until full write support lands.
|
||||
|
||||
### PDU Size & Optimization
|
||||
|
||||
| PLC | PDU Size | Max Data per Read |
|
||||
|
||||
Reference in New Issue
Block a user