Modbus Compliance: Read Only Registers


Thread Starter

Chris Niemuth

Our device is planning to support three commands 0x03 (Read Holding Registers), 0x04 (Read Input Registers), and 0x06 (Write Holding Registers). However, I am having disagreements with my colleagues about if supporting the 0x04 command is necessary. They want to have one memory map for all parameters and only use the 0x03 and 0x06 commands. They plan to return an error if a write to a read only register is attempted. I am willing to concede as long as this doesn't violate any chances at acquiring modbus compliance.

Does anyone know if read-only registers can be implemented in the memory map supported by the 0x03 and 0x06 commands?

It is common to map a mixture of read-only registers and read-write registers in the function code 03 block (40000 block of registers). The device should respond with an exception code when trying to write to a read-only register.
There is no exception code for "write to a read-only register". The Modbus function codes are designed to prevent that sort of error from even being possible. If you implement what you are saying, then what you have won't be Modbus and nobody else's software will be able to understand what error you are attempting to signal.

Modbus has a very simple, straightforward, and easy to understand way of doing exactly what you want. Just mirror the holding register data to the input registers and then implement just the 04 (read input registers) and 06 (write single holding register) commands. Then, just have valid holding register addresses only for those holding registers which need to be written to. Attempting to write to holding registers which don't exist will result in a 02 exception (invalid address).

This doesn't require any more memory, as you are not creating two separate memory arrays. All data is in the same array. You are just defining some addresses as being "read only" by declaring that they don't exist as far as function 06 (write register) is concerned. The read command can see all the registers, because there are no "missing registers" so far as the input registers are concerned.

To give you an example, suppose you defined 50 registers, and want the first 10 to be read-write and the rest to be read only. You define 10 holding register addresses from 0 to 9. You also define 50 input registers from 0 to 49. Input registers 0 to 9 are the same physical memory as the input registers, so whatever gets written to holding registers 0 to 9 is also in input registers 0 to 9.

Now, you can write to holding registers 0 to 9 using function 06. You can read the same data using function 04. You can also read the read only data using function 04. You can read all the data (read only and read-write) with a single function 04 call.

If someone attempts to write to register 10, they would get an exception of 2 (invalid address) since that holding register doesn't exist (as far as function 06 is concerned).

If you don't want the holding registers to be consecutive addresses, then that is permitted as well under Modbus. You could have holding registers 0, 10, 15, 22, and 23 while not having any of the others in between. That is, you can have "holes" in the middle of the address range.

This is how Modbus is intended to work. A read only register is an input register. A read write register is a holding register. You can overlay register types or have them completely separate. You don't have to worry about how to signal to the operator that they attempted to write to a read only register because there is no function code which they can use to attempt this.

So, the answer to your question is to simply implement function 04 instead of 03 and all your problems go away.
Thread starter Similar threads Forum Replies Date
S Modbus 2
A Modbus 4
A Modbus 1
M Modbus 4
A Modbus 2