93 lines
6.6 KiB
JSON
93 lines
6.6 KiB
JSON
{
|
||
"_description": "S7-1500 profile — DB1 (1024 bytes) + MB (256 bytes) + TM/CT (64 bytes each) with well-known seeds at named offsets for the smoke + byte-order + string + Timer/Counter tests. Big-endian Siemens wire order throughout.",
|
||
"areas": [
|
||
{
|
||
"area": "DB",
|
||
"index": 1,
|
||
"size": 1024,
|
||
"seeds": [
|
||
{ "_desc": "DB1.DBW0 — read-back probe, S7Driver default ProbeAddress target is MW0; this shadows it",
|
||
"offset": 0, "type": "u16", "value": 4242 },
|
||
{ "_desc": "DB1.DBW10 — i16 smoke value for SmokeI16 read path",
|
||
"offset": 10, "type": "i16", "value": -12345 },
|
||
{ "_desc": "DB1.DBD20 — i32 smoke value for SmokeI32 read path",
|
||
"offset": 20, "type": "i32", "value": 1234567890 },
|
||
{ "_desc": "DB1.DBD30 — f32 smoke value for SmokeF32 read path (IEEE-754 big-endian)",
|
||
"offset": 30, "type": "f32", "value": 3.14159 },
|
||
{ "_desc": "DB1.DBX50.3 — bool bit at byte-50 bit-3 for SmokeBool read path",
|
||
"offset": 50, "type": "bool", "value": true, "bit": 3 },
|
||
{ "_desc": "DB1.DBW100 — scratch for write-then-read round-trip tests; seeded 0",
|
||
"offset": 100, "type": "u16", "value": 0 },
|
||
{ "_desc": "DB1.STRING[200] — S7 string 'Hello' (max 32, cur 5)",
|
||
"offset": 200, "type": "ascii", "value": "Hello", "max_len": 32 },
|
||
|
||
{ "_desc": "DB1.DBW300 — span-planner gate (S7_1500SpanReadTests) starts here. Cluster A spans 300..320 and merges into ONE block read under the 16-byte gap budget. Every seed from 300 on is distinct and non-zero so a mis-sliced block can never accidentally match (the #536 zero-source trap).",
|
||
"offset": 300, "type": "u16", "value": 51001 },
|
||
{ "_desc": "DB1.DBW302 — cluster A, adjacent to DBW300 (gap 0)",
|
||
"offset": 302, "type": "i16", "value": -21001 },
|
||
{ "_desc": "DB1.DBD304 — cluster A, adjacent to DBW302 (gap 0)",
|
||
"offset": 304, "type": "i32", "value": 305419896 },
|
||
{ "_desc": "DB1 @308 — POISON in the 308..310 hole the span reads through; no tag maps here, so a mis-slice yields 0xDEAD rather than a zero that could pass by luck",
|
||
"offset": 308, "type": "u16", "value": 57005 },
|
||
{ "_desc": "DB1.DBX310.5 — cluster A bool (gap 2 from the DBD304 end)",
|
||
"offset": 310, "type": "bool", "value": true, "bit": 5 },
|
||
{ "_desc": "DB1 @311 — POISON in the 311..316 hole",
|
||
"offset": 311, "type": "u8", "value": 90 },
|
||
{ "_desc": "DB1 @312 — POISON in the 311..316 hole (0xDEADBEEF)",
|
||
"offset": 312, "type": "u32", "value": 3735928559 },
|
||
{ "_desc": "DB1.DBD316 — cluster A f32, gap 5 from the bool byte's end; seals the span at 300..320 = 20 bytes",
|
||
"offset": 316, "type": "f32", "value": 2.7182817 },
|
||
|
||
{ "_desc": "DB1.DBW400 — cluster B; 80 bytes past cluster A's end, so the 16-byte gap budget forces a SECOND span rather than one merged read",
|
||
"offset": 400, "type": "u16", "value": 40201 },
|
||
{ "_desc": "DB1.DBW402 — cluster B's second member; two members keep the span off the PrefersPerTagRead demotion",
|
||
"offset": 402, "type": "u16", "value": 40202 },
|
||
|
||
{ "_desc": "DB1.DBW500 — isolated narrow scalar: its own single-member span, demoted by PrefersPerTagRead into a leftover that rides the multi-var pass",
|
||
"offset": 500, "type": "u16", "value": 60001 },
|
||
{ "_desc": "DB1.DBW600 — second isolated narrow scalar, likewise a multi-var leftover",
|
||
"offset": 600, "type": "i16", "value": -32001 }
|
||
]
|
||
},
|
||
{
|
||
"area": "MK",
|
||
"index": 0,
|
||
"size": 256,
|
||
"seeds": [
|
||
{ "_desc": "MW0 — probe target for S7ProbeOptions.ProbeAddress default",
|
||
"offset": 0, "type": "u16", "value": 1 },
|
||
{ "_desc": "MW10 — span-planner gate: a narrow scalar in a DIFFERENT area from the DB1 leftovers. A block read can never merge across (area, DB); the multi-var pass can, so this pins that the leftover batching crosses the boundary.",
|
||
"offset": 10, "type": "u16", "value": 4097 }
|
||
]
|
||
},
|
||
{
|
||
"_desc": "TM (timers) — 64 bytes = 32 timer cells. A timer is a 2-byte S5TIME word and timer number N lives at byte offset 2*N, so the offsets below ARE the timer numbers doubled. Values are S5TIME-encoded (bits 12..13 = time base, the remaining three nibbles = a BCD 0..999 count) and each decodes to a distinct NON-ZERO duration, because a zero-valued timer reads the same as a timer that was never served at all (the #536 trap). ⚠️ Only T0 is readable through this fixture — see the CT note below and Docker/README.md §'Timer / Counter (TM / CT) areas'.",
|
||
"area": "TM",
|
||
"index": 0,
|
||
"size": 64,
|
||
"seeds": [
|
||
{ "_desc": "T0 @ byte 0 — 0x2456: base 2 (×1s), BCD 456 ⇒ 456.0 seconds. Device 0 is the one cell where snap7's address resolution and a real CPU's agree, so this is the seed S7_1500SpanReadTests asserts on.",
|
||
"offset": 0, "type": "u16", "value": 9302 },
|
||
{ "_desc": "T5 @ byte 10 — 0x1123: base 1 (×0.1s), BCD 123 ⇒ 12.3 seconds. Reachable only from a real CPU (S7_TIMER_NUMBER_ADDRESSING=1).",
|
||
"offset": 10, "type": "u16", "value": 4387 },
|
||
{ "_desc": "T9 @ byte 18 — 0x0250: base 0 (×0.01s), BCD 250 ⇒ 2.5 seconds. Real CPU only, as above.",
|
||
"offset": 18, "type": "u16", "value": 592 }
|
||
]
|
||
},
|
||
{
|
||
"_desc": "CT (counters) — 64 bytes = 32 counter cells, counter number N at byte offset 2*N. The driver surfaces a counter as the RAW big-endian word (S7Driver.DecodeScalarBlock via S7.Net's Counter.FromByteArray), so these seeds are plain u16 counts; distinct + non-zero for the same reason as the timers. ⚠️ snap7's server resolves the TM/CT request address as a BIT address (byte = addr>>3) instead of as a device NUMBER, while S7.Net (and a real CPU) put the device number there — so a read of C{n} lands on byte n>>3, and device 0 is the only n where the two conventions coincide. Live-probed 2026-08-17; see Docker/README.md.",
|
||
"area": "CT",
|
||
"index": 0,
|
||
"size": 64,
|
||
"seeds": [
|
||
{ "_desc": "C0 @ byte 0 — count 4711. The device-0 cell both conventions agree on; asserted by S7_1500SpanReadTests.",
|
||
"offset": 0, "type": "u16", "value": 4711 },
|
||
{ "_desc": "C7 @ byte 14 — count 31337. Reachable only from a real CPU (S7_TIMER_NUMBER_ADDRESSING=1).",
|
||
"offset": 14, "type": "u16", "value": 31337 },
|
||
{ "_desc": "C11 @ byte 22 — count 1234. Real CPU only, as above.",
|
||
"offset": 22, "type": "u16", "value": 1234 }
|
||
]
|
||
}
|
||
]
|
||
}
|