pymodbus-dev / pymodbus

A full modbus protocol written in python
Other
2.25k stars 919 forks source link

off-by-one on rtu server response to a 0x03 request #2147

Closed pythcoiner closed 6 months ago

pythcoiner commented 6 months ago

Versions

Pymodbus Specific

Description

There is an off-by-one on response to a 0x03 requests.

Code and Logs

here my server code:

logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

store = ModbusSequentialDataBlock(0x6500, [0x00] * 10)
store.setValues(0x6500, [1, 2, 3, 4, 5, 6, 7, 8, 9])  

slave_context = ModbusSlaveContext(di=None, co=None, hr=store, ir=None)
context = ModbusServerContext(slaves=slave_context, single=True)
print(context.slaves())
StartSerialServer(context=context, framer=ModbusRtuFramer, port="/dev/ttyUSB1", baudrate=115200)

in this setup if the server receive a <id> 0x03 65 00 00 01 <crc> <crc> request it should return <id> 0x03 02 00 01 <crc> <crc>, but instead it return data at index +1, here <id> 0x03 02 00 02 <crc> <crc>

here the response i get:

image

image

pythcoiner commented 6 months ago

after looking at the code it appear that its not a bug :

https://github.com/pymodbus-dev/pymodbus/blob/210ad31827ec45b07828794d9dc0b30f4c8805d2/pymodbus/datastore/context.py#L52

so why have zero_mode to False (off-by-one) as default? i guess it make the behaviour non-standard regarding modbus spec?

janiversen commented 6 months ago

Because it corresponds to with the modbus standard.

janiversen commented 6 months ago

Apart from that you are aware that zero mode affect the address not the values?

pythcoiner commented 6 months ago

Apart from that you are aware that zero mode affect the address not the values?

yeah i got it well :+1:

janiversen commented 6 months ago

Closing as this is not a bug, address zero is basically not allowed in modbus requests.

pythcoiner commented 6 months ago

Because it corresponds to with the modbus standard.

MODBUS Application Protocol Specification V1.1b3 Modbus April 26, 2012 http://www.modbus.org 15/50 6.3 03 (0x03) Read Holding Registers This function code is used to read the contents of a contiguous block of holding registers in a remote device. The Request PDU specifies the starting register address and the number of registers.In the PDU Registers are addressed starting at zero. Therefore registers numbered 1-16 are addressed as 0-15. The register data in the response message are packed as two bytes per register, with the binary contents right justified within each byte. For each register, the first byte contains the high order bits and the second contains the low order bits.

I get your point from the modbus spec i just read, but it feels weird to me that when i send a request to read Register 0x1000 i get the value of 0x1001 because i never had usage of devices having this behaviour to be honnest. I guess it is about several implementations having different interpretation of the spec.

janiversen commented 6 months ago

Well if it feels weird the use the zero_mode, that's why it's there.