package main import ( "sync" "time" "github.com/goburrow/serial" "lc/common/protocol" ) var _once sync.Once var _single *SerialMgr type SerialMgr struct { mu sync.Mutex mapSerial map[uint8]*serialPort mapSerialPort map[uint8]*protocol.SerialPort } func GetSerialMgr() *SerialMgr { _once.Do(func() { _single = &SerialMgr{ mapSerial: make(map[uint8]*serialPort), mapSerialPort: make(map[uint8]*protocol.SerialPort), } }) return _single } func openSerialPort(sp *protocol.SerialPort) (*serialPort, error) { config := serial.Config{Address: sp.Address, BaudRate: sp.BaudRate, DataBits: int(sp.DataBits), StopBits: int(sp.StopBits), Parity: sp.Parity, Timeout: time.Duration(sp.Timeout) * time.Microsecond} var err error var port serialPort port.setSerialConfig(config) port.SetAutoReconnect(SerialDefaultAutoReconnect) err = port.connect() if err != nil { return nil, err } return &port, nil } func (o *SerialMgr) AddSerialPorts(mapSP map[uint8]*protocol.SerialPort) { if len(mapSP) == 0 { return } o.mu.Lock() defer o.mu.Unlock() //先全部关闭并删除 for k, v := range o.mapSerial { _ = v.Close() delete(o.mapSerial, k) } //重新打开 for _, sp := range mapSP { var s protocol.SerialPort s = *sp port, _ := openSerialPort(&s) if port != nil { o.mapSerial[sp.Code] = port } } o.mapSerialPort = mapSP } func (o *SerialMgr) UpdateSerialPort(sp *protocol.SerialPort) error { if sp == nil { return nil } o.mu.Lock() defer o.mu.Unlock() if s, ok := o.mapSerial[sp.Code]; ok { //存在则关闭,并重新打开 _ = s.Close() //关闭 delete(o.mapSerial, sp.Code) } port, err := openSerialPort(sp) if port != nil { o.mapSerial[sp.Code] = port } o.mapSerialPort[sp.Code] = sp return err } func (o *SerialMgr) RemoveSerialPort(sp *protocol.SerialPort) error { if sp == nil { return nil } var err error o.mu.Lock() defer o.mu.Unlock() if s, ok := o.mapSerial[sp.Code]; ok { //存在则关闭,并重新打开 err = s.Close() //关闭 delete(o.mapSerial, sp.Code) } delete(o.mapSerialPort, sp.Code) return err } func (o *SerialMgr) GetSerialPort(code uint8) *serialPort { o.mu.Lock() defer o.mu.Unlock() if s, ok := o.mapSerial[code]; ok { return s } if sp, ok := o.mapSerialPort[code]; ok { port, _ := openSerialPort(sp) if port != nil { o.mapSerial[code] = port return port } } return nil }