You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ntool-biz/nmodbus/handler/fn_holdingregisters.go

111 lines
2.9 KiB
Go

package handler
import (
"git.noahlan.cn/noahlan/ntool-biz/nmodbus/protocol"
"git.noahlan.cn/noahlan/ntool-biz/nmodbus/serialize"
"git.noahlan.cn/noahlan/ntool-biz/nmodbus/util"
)
type ReadHoldingRegisters struct {
fnCode uint8
}
func NewReadHoldingRegisters(fnCode uint8) FunctionHandler {
return &ReadHoldingRegisters{fnCode: fnCode}
}
func (r *ReadHoldingRegisters) FnCode() uint8 {
return r.fnCode
}
// Function 读保持寄存器AI 功能码0x03
func (r *ReadHoldingRegisters) Function(s *Handler, req protocol.Packet, resp protocol.Packet) *protocol.MError {
register, numRegs, endRegister := serialize.RegisterAddressAndNumber(req.GetBody())
if endRegister > 65536 {
resp.SetBody([]byte{})
return &protocol.IllegalDataAddress
}
dataMgr := s.DataManager(req.GetAddress())
data := dataMgr.ReadHoldingRegisters(register, endRegister)
resp.SetBody(append([]byte{byte(numRegs * 2)}, util.Uint16ToBytes(s.byteOrder, data)...))
s.HandleLogic(r.fnCode, register, numRegs, data)
return &protocol.Success
}
////////////////////////////////////////////////////// WriteHoldingRegister
type WriteHoldingRegister struct {
fnCode uint8
}
func NewWriteHoldingRegister(fnCode uint8) FunctionHandler {
return &WriteHoldingRegister{fnCode: fnCode}
}
func (r *WriteHoldingRegister) FnCode() uint8 {
return r.fnCode
}
// Function 写单个保持寄存器 功能码0x06
func (r *WriteHoldingRegister) Function(s *Handler, req protocol.Packet, resp protocol.Packet) *protocol.MError {
data := req.GetBody()
register, value := serialize.RegisterAddressAndValue(data)
dataMgr := s.DataManager(req.GetAddress())
dataMgr.WriteSingleHoldingRegister(register, value)
resp.SetBody(data[0:4])
s.HandleLogic(r.fnCode, register, 1, value)
return &protocol.Success
}
////////////////////////////////////////////////////// WriteHoldingRegisters
type WriteHoldingRegisters struct {
fnCode uint8
}
func NewWriteHoldingRegisters(fnCode uint8) FunctionHandler {
return &WriteHoldingRegisters{fnCode: fnCode}
}
func (r *WriteHoldingRegisters) FnCode() uint8 {
return r.fnCode
}
// Function 写入 多个保持寄存器 功能码 0x10=16
func (r *WriteHoldingRegisters) Function(s *Handler, req protocol.Packet, resp protocol.Packet) *protocol.MError {
pkgData := req.GetBody()
register, numRegs, _ := serialize.RegisterAddressAndNumber(req.GetBody())
valueBytes := pkgData[5:]
var err *protocol.MError
var data []byte
if len(valueBytes)/2 != numRegs {
err = &protocol.IllegalDataAddress
}
// Copy data to memory
values := util.BytesToUint16(s.byteOrder, valueBytes)
dataMgr := s.DataManager(req.GetAddress())
valuesUpdated := dataMgr.WriteHoldingRegisters(values, register)
if valuesUpdated == numRegs {
err = &protocol.Success
data = pkgData[0:4]
} else {
err = &protocol.IllegalDataAddress
}
resp.SetBody(data)
s.HandleLogic(r.fnCode, register, numRegs, values)
return err
}