modbus icon indicating copy to clipboard operation
modbus copied to clipboard

Write function code for HandleHoldingRegisters

Open shantanoo opened this issue 2 years ago • 6 comments

In TCP server implementation, how to find whether the function code was 6 or 16 (0x10)? And how to respond to it specifically?

type HoldingRegistersRequest struct {
	ClientAddr string   // the source (client) IP address
	ClientRole string   // the client role as encoded in the client certificate (tcp+tls only)
	UnitId     uint8    // the requested unit id (slave id)
	Addr       uint16   // the base register address requested
	Quantity   uint16   // the number of consecutive registers covered by this request
	IsWrite    bool     // true if the request is a write, false if a read
	Args       []uint16 // a slice of register values to be set, ordered from
	                    // Addr to Addr + Quantity - 1 (for writes only)
}

shantanoo avatar Jul 17 '23 14:07 shantanoo

Pull Request #33

shantanoo avatar Jul 17 '23 17:07 shantanoo

Hi shantanoo,

first off, thanks for the pull request!

I'm trying to keep the code/API simple and concise, so I'm trying to understand the rationale behind this. Why would you need to differentiate between holding reg write opcodes?

simonvetter avatar Jul 30 '23 17:07 simonvetter

Need to take action based on opcode. E.g. only write multiple registers should be supported and single register should return error. Might be better to different handler functions for single and multiple registers to have one-to-one mapping as per modbus specification.

shantanoo avatar Jul 31 '23 05:07 shantanoo

only write multiple registers should be supported and single register should return error

If what you're trying to achieve is to make sure that multiple registers are being written atomically (instead of a single register), would testing on Quantity work in your handler? Something along those lines:

if isWrite && req.Quantity < 2 {
  err = ErrIllegalDataValue
  return
}

Note that your handler still wouldn't be able to tell if that request came through opcode 0x6 or through 0x10 with a single register, but that shouldn't be a concern for your use case.

Note that this technique can also be used on reads, if you ever want to ensure that reads are atomic as well.

simonvetter avatar Aug 01 '23 18:08 simonvetter

Actually I am trying to read the modbus request on TCP server/slave and get the data from RTU client/master. In that case, server don't know what type of request comes from the client. Hence needed to differentiate between function code 6 and 16 (0x10).

shantanoo avatar Aug 14 '23 18:08 shantanoo