|
|
|
|
package handler
|
|
|
|
|
|
|
|
|
|
import "sync"
|
|
|
|
|
|
|
|
|
|
// DataMgr 数据管理器
|
|
|
|
|
type DataMgr struct {
|
|
|
|
|
Address uint8 // 主机地址
|
|
|
|
|
|
|
|
|
|
coils []byte // 线圈(DO:数字输出)
|
|
|
|
|
discreteInputs []byte // 离散输入(DI:数字输入)
|
|
|
|
|
holdingRegisters []uint16 // 保持寄存器(AO:模拟输出)
|
|
|
|
|
inputRegisters []uint16 // 输入寄存器(AI:模拟输入)
|
|
|
|
|
|
|
|
|
|
mu sync.RWMutex
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewDataManager(address uint8) *DataMgr {
|
|
|
|
|
return &DataMgr{
|
|
|
|
|
Address: address,
|
|
|
|
|
coils: make([]byte, 65536),
|
|
|
|
|
discreteInputs: make([]byte, 65536),
|
|
|
|
|
holdingRegisters: make([]uint16, 65536),
|
|
|
|
|
inputRegisters: make([]uint16, 65536),
|
|
|
|
|
mu: sync.RWMutex{},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *DataMgr) ReadCoils(start, end int) []byte {
|
|
|
|
|
m.mu.RLock()
|
|
|
|
|
defer m.mu.RUnlock()
|
|
|
|
|
|
|
|
|
|
return m.coils[start:end]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *DataMgr) ReadDiscreteInputs(start, end int) []byte {
|
|
|
|
|
m.mu.RLock()
|
|
|
|
|
defer m.mu.RUnlock()
|
|
|
|
|
|
|
|
|
|
return m.discreteInputs[start:end]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *DataMgr) ReadHoldingRegisters(start, end int) []uint16 {
|
|
|
|
|
m.mu.RLock()
|
|
|
|
|
defer m.mu.RUnlock()
|
|
|
|
|
|
|
|
|
|
return m.holdingRegisters[start:end]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *DataMgr) ReadInputRegisters(start, end int) []uint16 {
|
|
|
|
|
m.mu.RLock()
|
|
|
|
|
defer m.mu.RUnlock()
|
|
|
|
|
|
|
|
|
|
return m.inputRegisters[start:end]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WriteSingleCoil 写单个线圈数据
|
|
|
|
|
func (m *DataMgr) WriteSingleCoil(idx int, val byte) {
|
|
|
|
|
m.mu.Lock()
|
|
|
|
|
defer m.mu.Unlock()
|
|
|
|
|
|
|
|
|
|
m.coils[idx] = val
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WriteSingleHoldingRegister 写入单个保持寄存器
|
|
|
|
|
func (m *DataMgr) WriteSingleHoldingRegister(idx int, val uint16) {
|
|
|
|
|
m.mu.Lock()
|
|
|
|
|
defer m.mu.Unlock()
|
|
|
|
|
|
|
|
|
|
m.holdingRegisters[idx] = val
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WriteCoils 写多个线圈数据
|
|
|
|
|
// idxList 表示预写入的线圈地址列表
|
|
|
|
|
// values 表示预写入的线圈数据,与地址列表一一对应
|
|
|
|
|
func (m *DataMgr) WriteCoils(idxList []int, values []byte) {
|
|
|
|
|
m.mu.Lock()
|
|
|
|
|
defer m.mu.Unlock()
|
|
|
|
|
|
|
|
|
|
for i, idx := range idxList {
|
|
|
|
|
m.coils[idx] = values[i]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *DataMgr) WriteHoldingRegisters(values []uint16, start int, end ...int) int {
|
|
|
|
|
m.mu.Lock()
|
|
|
|
|
defer m.mu.Unlock()
|
|
|
|
|
|
|
|
|
|
var e int
|
|
|
|
|
if len(end) == 0 {
|
|
|
|
|
e = len(m.holdingRegisters)
|
|
|
|
|
} else {
|
|
|
|
|
e = end[0]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return copy(m.holdingRegisters[start:e], values)
|
|
|
|
|
}
|