4 Star 6 Fork 3

王军 / golib

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
conn_serial.go 3.24 KB
一键复制 编辑 原始数据 按行查看 历史
package serialer
import (
"errors"
"io"
"log"
"runtime"
"strings"
"sync"
"time"
"gitee.com/haodreams/golib/logs"
)
// Serial 串口
type Serial struct {
Connect string
conn io.ReadWriteCloser
buf SafeBuffer
err error
lock *sync.RWMutex
HaveRecv bool //是否开启数据接收线程
isRunning bool
eventChan chan byte
}
const (
//ConvertString 默认的转换字符串
ConvertString = "/dev/ttyO"
)
// Closed 串口是否已经关闭
func (s *Serial) Closed() bool {
return !s.isRunning
}
// Setup 设置
func (s *Serial) Setup() (err error) {
s.lock = new(sync.RWMutex)
s.eventChan = make(chan byte, 30)
if len(s.Connect) > 3 {
if runtime.GOOS != "windows" {
ss := strings.ToUpper(s.Connect[:3])
if ss == "COM" {
s.Connect = ConvertString + s.Connect[3:]
}
}
}
_, _, _, _, _, _, err = FormatOption(s.Connect)
s.HaveRecv = true
return
}
func (s *Serial) read() {
buf := make([]byte, 1024)
logs.Info(s.Connect, "Start receive data")
for s.isRunning {
s.lock.RLock()
if s.conn == nil {
s.lock.RUnlock()
break
}
n, err := s.conn.Read(buf)
s.lock.RUnlock()
if err != nil {
if err.Error() != "EOF" {
s.err = err
log.Println(err)
time.Sleep(time.Second)
continue
}
}
if n > 0 {
logs.Debug("R: % 02X", buf[:n])
if s.buf.Len() > 8192 {
//s.buf.Reset()
s.buf.RemoveHead4K()
}
s.buf.Write(buf[:n])
s.eventChan <- 1
}
time.Sleep(time.Millisecond * 10)
}
logs.Info(s.Connect, "Stop receive data.")
}
// Open 打开
func (s *Serial) Open() (err error) {
logs.Info("Open serial:", s.Connect)
s.lock.Lock()
defer s.lock.Unlock()
s.conn, err = Open(s.Connect)
if err != nil {
return
}
if s.conn == nil {
err = errors.New("Open faied")
return
}
s.buf.Reset()
s.err = nil
s.isRunning = true
if s.HaveRecv {
go s.read()
}
return
}
// Close 关闭
func (s *Serial) Close() (err error) {
if s.conn != nil {
logs.Info("Close serial:", s.Connect)
err = s.conn.Close()
s.lock.Lock()
s.conn = nil
s.lock.Unlock()
}
s.isRunning = false
//log.Println("============close")
return
}
// Write 写数据
func (s *Serial) Write(p []byte) (n int, err error) {
if s.conn == nil {
err = errors.New("Not connected")
return
}
n, err = s.conn.Write(p)
if err == nil && n > 0 {
logs.Debug("S: % 02X", p[:n])
}
return
}
// Read 读数据
func (s *Serial) Read(p []byte) (n int, err error) {
//清空事件
numEvent := len(s.eventChan)
for ; numEvent > 0; numEvent-- {
<-s.eventChan
}
if s.conn == nil {
err = errors.New("Not connected")
return
}
if s.err != nil {
return 0, s.err
}
if s.buf.Len() > 0 {
n, err = s.buf.Read(p)
if err != nil {
return
}
if err == nil && n > 0 {
//logs.Info("R: % 02X", p[:n])
}
return
}
select {
case <-time.After(time.Second):
// err = errors.New("timeout")
return
case <-s.eventChan:
n, err = s.buf.Read(p)
if err != nil {
if err.Error() == "EOF" {
err = nil
}
//log.Println(err)
return
}
}
if err == nil && n > 0 {
//logs.Info("R: % 02X", p[:n])
}
return
}
// Len 获取buf 数据的长度
func (s *Serial) Len() int {
return s.buf.Len()
}
// Reset 清空数据
func (s *Serial) Reset() {
//logs.Debug("reset bufer")
s.buf.Reset()
}
Go
1
https://gitee.com/haodreams/golib.git
git@gitee.com:haodreams/golib.git
haodreams
golib
golib
56c05e20dd3e

搜索帮助

53164aa7 5694891 3bd8fe86 5694891