Description
What would you like to happen?
The 0.13.0 version of the Modbus driver introduced the endianness and byte swapping features, but there is still one feature that should be added - word swapping. Word swapping swaps sequential word pairs (or registers), which is relevant with 64-bit values. For example, with 4 registers totalling 8 bytes:
Big Endian :
[1, 2] [3, 4] [5, 6] [7, 8]
Big Endian with Word Swap:
[3, 4] [1, 2] [7, 8] [5, 6]
Big Endian with Word Swap and Byte Swap:
[4, 3] [2, 1] [8, 7] [6, 5]
I'm not sure if the LittleEndian was thought to be for this use originally, but as it reverses the entire sequence, it is conceptually different from Modbus word swapping for large data types.
I have created an implementation by extending the ModbusByteOrder
with additional members:
// [3, 4, 1, 2]
// [3, 4, 1, 2, 7, 8, 5, 6]
BIG_ENDIAN_WORD_SWAP,
// [2, 1, 4, 3]
// [6, 5, 8, 7, 2, 1, 4, 3]
LITTLE_ENDIAN_WORD_SWAP,
// [4, 3, 2, 1]
// [4, 3, 2, 1, 8, 7, 6, 5]
BIG_ENDIAN_WORD_SWAP_BYTE_SWAP,
// [1, 2, 3, 4]
// [5, 6, 7, 8, 1, 2, 3, 4]
LITTLE_ENDIAN_WORD_SWAP_BYTE_SWAP
And in addition, to complement byteSwap()
, I've added wordSwap()
:
public static byte[] wordSwap(byte[] in) {
if (in.length % 2 != 0) {
throw new PlcRuntimeException("Input byte array length must be a multiple of 2 for word swapping.");
}
byte[] out = new byte[in.length];
for (int i = 0; i < in.length; i += 4) {
out[i] = in[i + 2];
out[i + 1] = in[i + 3];
out[i + 2] = in[i];
out[i + 3] = in[i + 1];
}
return out;
}
So, depending on the ModbusByteOrder
, a combination of these methods are applied. My implementation currently is built on top of the previous PR #2055, I could either expand that PR to be more generic for Modbus improvements, or if it can be handled first, I can make a separate PR with the implementation.
Programming Languages
- plc4j
- plc4go
- plc4c
- plc4net
Protocols
- AB-Ethernet
- ADS /AMS
- BACnet/IP
- CANopen
- DeltaV
- DF1
- EtherNet/IP
- Firmata
- KNXnet/IP
- Modbus
- OPC-UA
- S7