feat(modbus): String[] and BitInRegister[] writes

U3: both array shapes read fine but every write failed BadInternalError.
String[] now encodes each element at its register width (StringLength chars,
2 per register); BitInRegister[] reads the span once, flips the addressed bit
of each register and writes the span back with FC16 (per-register RMW locks
taken in ascending order). A length mismatch is BadOutOfRange and sends
nothing. DriverArrayWriteSupport (outside this lane) still advertises these
nodes read-only - recorded as follow-up F1 in the parity test.

Refs #741
Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
Joseph Doherty
2026-10-22 15:26:59 -04:00
parent 2ef3cd0df2
commit 1adc9d65e1
3 changed files with 146 additions and 5 deletions
@@ -35,10 +35,8 @@ public sealed class ModbusArrayWriteSupportParityTests
/// </summary>
private static bool PendingF1(ModbusRegion region, ModbusDataType dataType) =>
(region == ModbusRegion.Coils && dataType != ModbusDataType.Bool)
|| (region == ModbusRegion.HoldingRegisters && dataType is ModbusDataType.String or ModbusDataType.BitInRegister && PendingU3);
|| (region == ModbusRegion.HoldingRegisters && dataType is ModbusDataType.String or ModbusDataType.BitInRegister);
// Flipped to true by the U3 commit (String[] / BitInRegister[] encoders).
private const bool PendingU3 = false;
public static TheoryData<ModbusRegion, ModbusDataType> PendingShapes()
{