package main import ( "errors" "log" "time" "go.bug.st/serial" ) const ( portName = "/dev/ttyS9" baudRate = 115200 timeout = 5 * time.Second reopenDelay = 500 * time.Millisecond ) func main() { log.Println("goserial test tool started") log.Printf("configuration: port=%s baud=%d", portName, baudRate) for { if err := runTest(); err != nil { log.Printf("test run failed, will reopen port after delay: %v", err) time.Sleep(reopenDelay) continue } } } func runTest() error { log.Println("opening serial port") // 打开端口 port, err := serial.Open(portName, &serial.Mode{ BaudRate: baudRate, }) if err != nil { log.Printf("failed to open serial port %s: %v", portName, err) return err } defer func() { log.Println("closing serial port") if err := port.Close(); err != nil { log.Printf("failed to close serial port: %v", err) } }() // 设置读取超时 if err := port.SetReadTimeout(timeout); err != nil { log.Printf("failed to set read timeout: %v", err) return err } log.Printf("read timeout set: %v", timeout) log.Println("start reading from serial port (synchronous mode)") // 创建缓冲区用于读取数据 buffer := make([]byte, 24) // 同步读取循环 for { n, err := port.Read(buffer) if err != nil { // 检查是否是超时错误 if err.Error() == "i/o timeout" { log.Println("serial port read timeout occurred, exiting read loop") // 超时后退出循环,重新打开端口 break } // 使用类型断言检查是否是PortError var portErr *serial.PortError if errors.As(err, &portErr) { // 检查错误代码是否为PortClosed if portErr.Code() == serial.PortClosed { log.Println("port closed, exiting read loop") break } } // 其他错误 log.Printf("error reading from serial port: %v", err) return err } if n > 0 { log.Printf("data received: bytes=%d data=%v", n, buffer[:n]) } } // 正常退出读取循环 log.Println("read loop exited normally") return nil }