From e6599e17a899f37b2e9732a9d8073d74c11441d6 Mon Sep 17 00:00:00 2001 From: Yuriy Ponomarev Date: Wed, 26 Sep 2018 11:01:56 +0300 Subject: [PATCH 1/5] Custom baudrates on linux --- serial_linux.go | 35 +++++++++++++++++++++++++++++++++++ serial_posix.go | 14 ++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/serial_linux.go b/serial_linux.go index 35606b2..45bae5b 100644 --- a/serial_linux.go +++ b/serial_linux.go @@ -101,3 +101,38 @@ func fdisset(fd int, fds *syscall.FdSet) bool { idx, pos := fdget(fd, fds) return fds.Bits[idx]&(1< 0 { + c.BaudRate = custom_baudrate + ok, errno := setSpecialBaudrate(p.fd, custom_baudrate) + if !ok { + return error(errno) + } + } + return } From 4def6ef9a94833f8f1b84602b496cd2745336ac1 Mon Sep 17 00:00:00 2001 From: Edgar <44380483+Edgar242@users.noreply.github.com> Date: Fri, 14 Jun 2019 17:27:56 -0500 Subject: [PATCH 2/5] When the port Address number was grater than 10 the port couldn't be oppened, and a solution to this problem is adding those back slashes, other libraries are using this method. --- serial_windows.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/serial_windows.go b/serial_windows.go index 1eeb14b..1ff72af 100644 --- a/serial_windows.go +++ b/serial_windows.go @@ -156,13 +156,17 @@ func (p *port) setSerialConfig(c *Config) error { } func newHandle(c *Config) (handle syscall.Handle, err error) { + name := c.Address + if len(name) > 0 && name[0] != '\\' { + name = "\\\\.\\" + name + } handle, err = syscall.CreateFile( - syscall.StringToUTF16Ptr(c.Address), + syscall.StringToUTF16Ptr(name), syscall.GENERIC_READ|syscall.GENERIC_WRITE, - 0, // mode - nil, // security + 0, // mode + nil, // security syscall.OPEN_EXISTING, // create mode - 0, // attributes - 0) // templates + 0, // attributes + 0) // templates return } From 51016b570a6ce27593c36d23dd095ec3685ebc51 Mon Sep 17 00:00:00 2001 From: Iurii Ponomarev Date: Wed, 25 Dec 2019 15:47:24 +0300 Subject: [PATCH 3/5] go module created --- go.mod | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 go.mod diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..02c969c --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/y-ponomarev/serial + +go 1.13 From 5a71da530865cb315af89cac2f56df09779ff96f Mon Sep 17 00:00:00 2001 From: Aleksey Bakin Date: Mon, 27 Dec 2021 10:15:37 +0300 Subject: [PATCH 4/5] fix: use syscall poll instead of select to avoid limitations --- serial_posix.go | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/serial_posix.go b/serial_posix.go index 6d25b2d..64939f0 100644 --- a/serial_posix.go +++ b/serial_posix.go @@ -85,33 +85,33 @@ func (p *port) Close() (err error) { // Read reads from serial port. Port must be opened before calling this method. // It is blocked until all data received or timeout after p.timeout. func (p *port) Read(b []byte) (n int, err error) { - var rfds syscall.FdSet + fds := []unix.PollFd{{Fd: int32(p.fd), Events: unix.POLLIN}} + deadline := time.Now().Add(p.timeout) - fd := p.fd - fdset(fd, &rfds) - - var tv *syscall.Timeval - if p.timeout > 0 { - timeout := syscall.NsecToTimeval(p.timeout.Nanoseconds()) - tv = &timeout - } for { - // If syscall.Select() returns EINTR (Interrupted system call), retry it - if err = syscallSelect(fd+1, &rfds, nil, nil, tv); err == nil { - break + timeout := -1 + if p.timeout > 0 { + timeout = int(deadline.Sub(time.Now()).Milliseconds()) } - if err != syscall.EINTR { - err = fmt.Errorf("serial: could not select: %v", err) - return + + n, err := unix.Poll(fds, timeout) + if err != nil { + if errors.Is(err, syscall.EINTR) { + continue + } + return 0, fmt.Errorf("serial: could not poll: %v", err) + } + + if n == 0 { + return 0, ErrTimeout + } + + if fds[0].Revents&unix.POLLIN == unix.POLLIN { + break } } - if !fdisset(fd, &rfds) { - // Timeout - err = ErrTimeout - return - } - n, err = syscall.Read(fd, b) - return + + return syscall.Read(p.fd, b) } // Write writes data to the serial port. From 9393de881e7e63ad5d66e7cba85231300db922b5 Mon Sep 17 00:00:00 2001 From: Iurii Ponomarev Date: Mon, 31 Jan 2022 17:27:38 +0300 Subject: [PATCH 5/5] fix build after merge PR #3 --- go.mod | 2 ++ go.sum | 2 ++ serial_posix.go | 1 + 3 files changed, 5 insertions(+) create mode 100644 go.sum diff --git a/go.mod b/go.mod index 02c969c..c556438 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/y-ponomarev/serial go 1.13 + +require golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..15089f2 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/serial_posix.go b/serial_posix.go index 79bc7c2..009e878 100644 --- a/serial_posix.go +++ b/serial_posix.go @@ -10,6 +10,7 @@ import ( "syscall" "time" "unsafe" + "golang.org/x/sys/unix" ) // port implements Port interface.