ModBus Exception on read only register

E

Thread Starter

Enrico

Hi,
i'm writing a source code for slave module to connect in Modbus net but i'm in a little confusion about exception code.

What exception code does the unit transmit if the master attempts to write a read only register?
 
Hello,
AFIK, MODBUS does not define any registers as "read only".

Having said that, I would expect an exception code 3: illegal data value.

I would be sure to document it for users.

HTH,

Mark
http://www.peakhmi.com
 
Acutally Input registers 0x04 and input coils (discrete inputs) 0x02 are essentialy read only. You cannot write to them from a master as there is no function code to do so. For register that can be written to there is no way in the protocol specification to designate them as read only.

However in my job I have seen many devices that have impimented read only data in holding registers. They simply reture an exception code of 0x01 (illegal function) if you try to write to them.

Keep in mind that this is a design feature that is set by the hardware manufacturer only.

Fred Loveless
Senior Application Engineer
Kepware Technologies
http://www.kepware.com
 
I beg to differ. The Modbus standard does define read/write for the 4 basic data registers in which 'input' registers are read-only. I cite the MODBUS APPLICATION PROTOCOL SPECIFICATION V1.1b December 28, 2006 http://www.Modbus-IDA.org

pg 6:
4.3 MODBUS Data model

MODBUS bases its data model on a series of tables that have distinguishing characteristics.

The four primary tables are:
~
~
Input Registers 16-bit word Read-Only this type of data can be provided by an I/O system
~

I would expect Modbus Exception code 01, Illegal Function, in response to a write command to
a read-only input register.

for reference,see pg 49, MODBUS APPLICATION PROTOCOL SPECIFICATION V1.1b

Modbus Exception Code 01
Name: ILLEGAL FUNCTION
Meaning: The function code received in the query is not an allowable action for the server (or slave). This may be because the function code is only applicable to newer devices, and was not implemented in the unit selected. It could also indicate that the server (or slave) is in the wrong state to process a request of this type, for example because it is unconfigured and is being asked to return register values.

Issac
 
Read-only registers are called "Input Registers". Read-write registers are called "Holding Registers". The master can't even attempt to write to an input register, because there is no Modbus function code to do that. The protocol avoids the issue altogether by design, therefore the problem simply doesn't arise. That is why there are two types of registers.

Have a look at the list of Modbus functions. There are functions for reading both holding and input registers, and there are functions for writing to holding registers. There are no functions for writing to input registers.
 
Hello,
Differing allowed. I knew when I posted the reply someone would come up and say but but but.

It only made sense to me that he was referring to registers that COULD be written to marked as "read only" for his device. This is very common for slave devices that are not PLCs and use MODBUS as a means to publish status information of the device.

And that he was using a WRITE function code.

If he was not using a legal function code then the reply would be illegal function and that would be that.

None of the registers that support a write function are "read only" per the spec..

Ciao,
Mark
http://www.peakhmi.com
 
I will use the exception 0x01.

I'm trying to do a gateway and I don't know the R/W property of the parameters. For this reason I chose to insert all parameters in the Holding registers table.

"It is perfectly acceptable, and very common, to regard all four tables as overlaying one another, if this is the most natural interpretation on the target machine in question" (4.3 MODBUS Data model).

Thank you for your support.

Enrico

 
Sorry for digging up this thread but I could not find a newer regarding my problem. My question is regarding the same issue.

How should a modbus server (slave) react on a "write multiple registers" if an input register was addressed instead of an holding register?

exception code 0x01 or 0x02
0x01 because it is a illegal function for that address.
or 0x02 because it is an illegal address for that function?

Just because the modbus standard does not support an write to a read register, I still have to give an answer if a client asks me...
 
"Write multiple registers" (function 16) writes to holding registers. The type of register being addressed is determined by the function code. There is no function code for writing to input registers, so the problem doesn't arise. Modbus avoids that problem by design.
 
You can't actually address an input register from a Function 6 or 16. Any register addressed by those functions is by definition a holding register. Different functions work on completely different register spaces. Even if the register number happened to match an input register, it would be like sending a letter to 123 Main street in Boston instead of 123 Main street in Miami. The write would go to the (possibly invalid) holding register with the same number even if you intended it for an input register. The slave has no way of knowing you meant it for an input register, because the 3x vs 4x register numbering system has been stripped off in the actual binary request message being sent.

On the matter of Read-only holding registers, everyone seems to have a different opinion on how it should be done. I have implemented it two different ways on slaves I have developed. The first way (and probably more correct) is to simply accept the write, send the success response, and then throw away the new value as if the slave had overwritten the new value with the old value internally. The second method I have implemented is to return Exception 0x02, invalid register, with the reasoning behind that decision being that for the particular function requested (6 or 16), that register number is not supported by this device.
 
Just to clarify this a bit more, here's what a request for function 16 (write multiple registers) looks like (excluding the header data):

Function code: 1 byte (contains 16 in this case)
Starting Address: 2 bytes
Quantity of Registers: 2 bytes
Byte Count: 2 bytes
Registers Value: N x 2 bytes (N = number of registers to write)

The "Starting Address" will be a number between 0 and 65535. This represents where in the holding registers the first value is to be written. 0 = holding register 1, 1 = holding register 2, etc.

So, it really isn't possible for function 16 to "address" the input registers. The protocol just doesn't work that way.
 
My reading of the Modbus specification is that you should only ever return exception code 2 "Invalid data address" if the client specifies a register offset of greater than 65535. The only way it can do this is with a read/write of multiple registers where the start offset plus the number of registers is greater than 65535.

The reasoning behind this is that the server itself is not supposed to require any knowledge of the layout of registers in the application, nor of what register values are valid.

Please correct me if I have got this wrong.

Many clients rely on reads and writes of unconfigured register offsets having no effect (i.e. fail silently), so that they can optimise messages by reading/writing a whole bunch of contiguous registers in a single message.

On this basis, an attempted write to a read-only holding register should 'succeed' but not change the value of the register.
 
L

Lynn August Linse

Given that I live and work in the real world, I don't worry much about a spec which was written "after the fact" and doesn't cover the most important gothca's (field-problems) in creating a marketable "slave device". I have dealt with Modbus/TCP to serial bridging for 14 years now and we have a constant stream of customers with 100% compliant slave devices in need to "fixes" due to their application.

First, make sure *ALL* of your data is available in the 4x table (period) - because things like Modicon IO Scanner (unless it has changed) only support reading/writing the 4x area. Any vendor putting data into the 0x/1x/3x area which cannot be seen in the 4x area is just creating field support problems. Once all data is available in the 4x area, you are free to mirror it also into the other 3 areas as desired.

Second, the exact exception code you return is not very important - it is the fact that an exception is returned which is important. The Modbus exceptions are so limited in scope that you rarely will find the "correct" code. Just make sure you document what you do.

Third, make sure you group the read-only stuff in a distinct area - say the range 4x09001 to 4x09999. Do not mix/interleave read-only and read-write registers as things like OPC try to optimize messages & may try to handle larger blocks than required.

Again, my goal is for you to produce a marketable product with lower support costs. Much of the advice given above will result in problematic support and perhaps even lost sales. Forcing use of the 3x and 1x areas is especially problematic.

Regards
- Lynn August Linse, Industrial Specialist, Digi
 
In reply to Ian Goldby: The Modbus spec says the following about exception 2 (ILLEGAL DATA ADDRESS):

"The data address received in the query is not an allowable address for the server (or slave). More specifically, the combination of reference number and transfer length is invalid. For a controller with 100 registers, the PDU addresses the first register as 0, and the last one as 99. If a request is submitted with a starting register address of 96 and a quantity of registers of 4, then this request will successfully operate (address-wise at least) on registers 96, 97, 98, 99. If a request is submitted with a starting register address of 96 and a quantity of registers of 5, then this request will fail with Exception Code 0x02 “Illegal Data Address” since it attempts to operate on registers 96, 97, 98, 99 and 100, and there is no register with address 100."

In other words, so far as the Modbus protocol is concerned, if a request attempts to read to or write from an address which does not exist the server (slave) should return exception 2. Furthermore, a slave may not necessarily implement all possible addresses in the address range (in the above example, only addresses up to 99 exist).

Now if a server were to discard the data for writes to registers 40 to 50, and to always return zeros for reads on those registers, then that appears to be permitted by the protocol. It is arguable in that case whether those registers "exist" or whether the server is simply "over writing" them with some other value after each write. So far as an outside observer is concerned, it is not possible to tell the difference between those two cases.

However, so far as the protocol is concerned, if a request to read or write an address does not return exception 2, then the address exists.

As for a "read only holding register", that is a contradiction in terms. Holding registers are never read only. However, the server could of course discard the write to that register. To an outside observer, this would look like the value was written, but then something else immediately overwrote it.

Normally though, a "read only register" is an input register. If a vendor wants to allow a customer to read a mixture of input and holding registers in a single operation, the normal and expected solution is to simply copy those holding registers to the input registers so the user can read them all with function 4 (read input registers). While I said "copy", that of course is how it looks from the outside. Logical Modbus addresses do not have to correspond to physical memory addresses so there is no need for more than one actual copy of the data.

However, the point remains that exception 2 (illegal address) does cover more than just addresses greater than 65535. It covers any address which the server wishes to indicate as invalid. A client should normally be able to expect that if a read or write does not return exception 2, then all affected addresses exist. Furthermore, a client cannot expect that all addresses from 0 to 65535 exist. If a client exhibits behaviour which does not meet these requirements and there is a problem, then it is the client which is at fault and not the server.
 
I've reviewed my earlier reply of "17 December, 2009 - 11:05 am", and I see that it is a very long "how many angels can dance on the head of a pin" type answer and that none of it had much to do with the original question.

However, it has occurred to me though that the customer question might have really been about what would happen if incorrect or conflicting parameters were entered in the client (master). If the client accepts incorrect or conflicting parameters, then it could appear to the user that they are writing to input registers.

It is difficult to say what the client will actually do in this hypothetical case. Due to the way that the messages are formatted however, it is not possible to send a message that actually writes to input registers.
 
F

Fred Loveless

There are cases where manufacturers of devices that do modbus will have data in holding registers that they do not allow writes to. I have seen 3 separate actions here.

1. Do not report any exception code just ignore the write attempt.

2. respond with an exception code 0x01 (illegal function).

3. respond with an exception code 0x06 (slave busy).

I would say the most acceptable is #2 as it is a function that is not supported for that address.
 
M

Michael Mellish

I have been working with the Modbus Protocol since 1979 and have implemented hundreds of masters, and helped numerous 3rd parties develop slave devices.

1.) MANY Slave devices (including Modicon "984" controllers) have the ability to make 4XXXX references "Read Only". The slave had the ability to decide to accept the message and to ignore the content that conflicts with its configuration. As I work today - I am connecting 4 distinct vendor products (MBTCP devices) that all provide data via 4XXXXX registers but define only a limited window of "Setpoints" that can be remotely modified.

2.) I can't say off the top of my head what response any of these devices provide IF you attempt to write to these areas. My personal recommendation would be an exception response BUT NOT an invalid command (which might be interpreted as some sort of communication error as opposed to invalid data point - consider using an code like 8 that isn't defined by ML-MBUS-300 (the original Modbus Protocol Guide) so that when someone calls your tech support to ask - you have a VERY CLEAR understanding that they are writing to protected memory).

3.) In General it is useful to keep Slave Interfaces "Simple". Most today use only 0XXXXX and 4XXXXX data types (I haven't seen anything with input registers & discrete inputs in several years). They keep 0XXXXX as bits so they are easy to individually write from the host - like to start or stop something. Just like the 4XXXXX discussion - you can create a "Read Only" block and a user writable block. To change only a single bit in a register isn't very easy with standard Modbus Functions.

4.) It is also helpful to group data in commonly used chunks. A single 4xxxx read command can acquire 123 Words of data. So for example if you are reading from a Power Meter - then group together Voltage, Current, VA, AP etc within a single block that can be read with one command. Leaving a Gap and then following with another data block of related information makes for easy host data collection.

5.) Many slaves also copy the coil data (0xxxx bits)as a block of contiguous registers - thus the host can read the data as part of other data collection of 4XXXX registers and will have fewer transactions to process.

6.) Please also add a block of registers that can provide the core data about your device:
a.) Vendor Name (typically up to 32 x 4xxxx)
b.) Product Name (typically up to 32 x 4xxxx)
c.) Product Part # (typically up to 32 x 4xxxx)
d.) Product Serial #(typically up to 16 x 4xxxx)
e.) Range of 0XXXXX, 4XXXXX supported
Other nice features to store in 4xxxxx and allow the user to write to are:
a.) Date of Installation
b.) Date of FAT
c.) Date placed in service
f.) User Designation(s) for device like name, ISA Tag, Asset Tag, physical location

Hope this is useful..
 
Mike, great to see your name pop up. Very good information.

And then there are the slave devices that reply with 2 registers when you only asked to read the contents of one. These slave devices have the 4xxxx references arranged in areas, one of which is floating point. And, of course, FP takes 2 registers so it automatically sends 2 in the response. Result is error, requested 1, received 2.
 
Top