package main import ( "sync" "time" "github.com/goburrow/serial" "github.com/sirupsen/logrus" "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 serial serialPort serial.setSerialConfig(config) serial.SetAutoReconnect(SerialDefaultAutoReconnect) err = serial.connect() if err != nil { logrus.Errorf("打开串口[code=%d,address=%s]失败:%s", sp.Code, sp.Address, err.Error()) return nil, err } logrus.Infof("打开串口[code=%d,address=%s]成功", sp.Code, sp.Address) return &serial, 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 newsp, _ := openSerialPort(&s) if newsp != nil { o.mapSerial[sp.Code] = newsp } } 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 { //存在则关闭,并重新打开 err := s.Close() //关闭 if err != nil { logrus.Errorf("关闭串口[code=%d,address=%s]失败:%s", sp.Code, sp.Address, err.Error()) } delete(o.mapSerial, sp.Code) } newsp, err := openSerialPort(sp) if newsp != nil { o.mapSerial[sp.Code] = newsp } 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 { newsp, _ := openSerialPort(sp) if newsp != nil { o.mapSerial[code] = newsp return newsp } } return nil }