fix(driver-modbus-addressing): resolve High code-review finding (Driver.Modbus.Addressing-001)
The DL205 family-native branch routed every V-prefixed address through DirectLogicAddress.UserVMemoryToPdu, a plain octal-to-decimal decode. DL205/DL260 system V-memory (V40400 and up) is not a simple octal decode: the CPU relocates the system bank to Modbus PDU 0x2100. Octal-decoding V40400 produced 16640 (0x4100), the wrong register, so any tag addressing a system register through the grammar string silently read/wrote the wrong PLC memory. - Add DirectLogicAddress.VMemoryToPdu, which decodes the octal V-address, detects the system bank (octal >= V40400 == SystemVMemoryOctalBase) and relocates it through SystemVMemoryToPdu to PDU 0x2100; user-bank addresses keep the plain octal decode. - ModbusAddressParser's DL205 V branch now calls VMemoryToPdu instead of UserVMemoryToPdu. UserVMemoryToPdu is retained for user-bank-only callers. - Correct the ModbusFamilyParserTests V40400 assertion (16640 -> 0x2100) and add system-bank regression cases plus direct helper coverage. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,8 +17,8 @@ public sealed class ModbusFamilyParserTests
|
||||
[Theory]
|
||||
[InlineData("V0", 0)]
|
||||
[InlineData("V2000", 1024)] // octal 2000 = decimal 1024
|
||||
[InlineData("V40400", 16640)] // octal 40400 = decimal 16640 (system bank in user mapping per the helper)
|
||||
public void DL205_VMemory_To_HoldingRegisters(string addr, int expectedOffset)
|
||||
[InlineData("V7777", 4095)] // octal 7777 = decimal 4095, top of the user bank example
|
||||
public void DL205_UserVMemory_To_HoldingRegisters(string addr, int expectedOffset)
|
||||
{
|
||||
var p = ModbusAddressParser.Parse(addr, ModbusFamily.DL205);
|
||||
p.Region.ShouldBe(ModbusRegion.HoldingRegisters);
|
||||
@@ -26,6 +26,32 @@ public sealed class ModbusFamilyParserTests
|
||||
p.DataType.ShouldBe(ModbusDataType.Int16);
|
||||
}
|
||||
|
||||
// Regression: Driver.Modbus.Addressing-001. DL205/DL260 system V-memory (V40400+) is NOT a
|
||||
// plain octal decode — the CPU relocates the system bank to Modbus PDU 0x2100. Octal-decoding
|
||||
// V40400 yields 16640 (0x4100), the WRONG register. Per docs/v2/dl205.md §V-Memory Addressing,
|
||||
// V40400 must map to PDU 0x2100 (decimal 8448) and the bank is contiguous from there.
|
||||
[Theory]
|
||||
[InlineData("V40400", 0x2100)] // system base
|
||||
[InlineData("V40401", 0x2101)] // next register — contiguous, +1 decimal
|
||||
[InlineData("V40410", 0x2108)] // octal 40410 = base + octal(10) = base + 8 decimal
|
||||
public void DL205_SystemVMemory_To_HoldingRegisters_SystemBank(string addr, int expectedOffset)
|
||||
{
|
||||
var p = ModbusAddressParser.Parse(addr, ModbusFamily.DL205);
|
||||
p.Region.ShouldBe(ModbusRegion.HoldingRegisters);
|
||||
p.Offset.ShouldBe((ushort)expectedOffset);
|
||||
p.DataType.ShouldBe(ModbusDataType.Int16);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DL205_SystemVMemory_Helper_Routes_Through_SystemBank()
|
||||
{
|
||||
// Direct helper coverage: VMemoryToPdu routes user vs system; the legacy
|
||||
// UserVMemoryToPdu is the plain octal decoder used only for the user bank.
|
||||
DirectLogicAddress.VMemoryToPdu("V40400").ShouldBe((ushort)DirectLogicAddress.SystemVMemoryBasePdu);
|
||||
DirectLogicAddress.VMemoryToPdu("V2000").ShouldBe((ushort)1024);
|
||||
DirectLogicAddress.UserVMemoryToPdu("V40400").ShouldBe((ushort)16640); // plain octal decode — user-bank only
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DL205_Y_Output_Maps_To_Coils_Bank()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user