mikepb / go-serial

Go binding to libserialport for serial port functionality.
53 stars 28 forks source link

Couldn't get this to work with Socat #1

Closed jimbojsb closed 9 years ago

jimbojsb commented 9 years ago

This library works great under Linux on the Raspberry Pi. However, I generally develop on a Mac and was trying to emulate the devices involved for testing and debugging. I have two "fake" PTY's installed with Socat (/dev/ttys003, /dev/ttys004). I have been unsuccessful so far at making this code open either of these ports. It works perfectly with real physical hardware. I couldn't see where it was actually failing, but the error message is:

Invalid arguments were passed to the function
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x4034053]

goroutine 16 [running]:
runtime.panic(0x40f6380, 0x41ab2e4)
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/panic.c:279 +0xf5
github.com/mikepb/serial.(*Port).Write(0x0, 0xc208000280, 0x4, 0x8, 0x8, 0x0, 0x0)
    /Users/josh/projects/propellerhead/src/github.com/mikepb/serial/serial.go:972 +0x263
main.main()
    /Users/josh/projects/propellerhead/src/serialtest.go:16 +0x17a

goroutine 19 [runnable]:
runfinq()
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/mgc0.c:2606
runtime.goexit()
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/proc.c:1445

goroutine 17 [syscall]:
runtime.goexit()
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/proc.c:1445
exit status 2

from the following Go code

package main

import (
    "github.com/mikepb/serial"
    "fmt"
)

func main() {
    info, err := serial.PortByName("/dev/ttys003")
    config := serial.RawOptions
    config.FlowControl = serial.FLOWCONTROL_RTSCTS
    config.BitRate = 9600
    port, err := info.OpenPort(&config)
    fmt.Println(err)
    port.Write([]byte("test"))
}

PTYs created with: socat -x -v PTY,raw,echo=0,link=tty1 PTY,raw,echo=0,link=tty2

mikepb commented 9 years ago

Hi @jimbojsb, thank you for the bug report!

I added the SetDebug method to enable debugging in libserialport:

serial.SetDebug(true)

I also pushed some changes I hadn't committed to support RTS/CTS and DTR/DSR directly.

Here's the output after enabling internal debugging:

sp_set_debug_handler returning.
sp_get_port_by_name(/dev/ttys003, 0xc208018e30) called.
Building structure for port /dev/ttys003.
Getting serial port list.
Iterating over results.
get_port_details returning SP_OK.
sp_get_port_by_name returning SP_OK.
sp_copy_port(0x4700010, 0xc208040190) called.
Copying port structure.
sp_get_port_by_name(/dev/ttys003, 0xc208040190) called.
Building structure for port /dev/ttys003.
Getting serial port list.
Iterating over results.
get_port_details returning SP_OK.
sp_get_port_by_name returning SP_OK.
sp_copy_port returning 0.
sp_open(0x4700070, 0x1) called.
Opening port /dev/ttys003.
get_config(0x4700070, 0x7fff5fbff800, 0x7fff5fbff7d8) called.
Getting configuration for port /dev/ttys003.
sp_last_error_message() called.
sp_last_error_message returning Inappropriate ioctl for device.
get_config returning SP_ERR_FAIL: TIOCMGET ioctl failed: Inappropriate ioctl for device.
sp_free_error_message(Inappropriate ioctl for device) called.
sp_free_error_message returning.
sp_close(0x4700070) called.
Closing port /dev/ttys003.
sp_close returning SP_OK.
sp_open returning SP_ERR_FAIL.
sp_new_config(0xc2080401a0) called.
sp_new_config returning SP_OK.
sp_get_config(0x4700070, 0x4700100) called.
sp_get_config returning SP_ERR_ARG: Invalid port fd.

I traced the error to serialport.c:1485:

    if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0)
        RETURN_FAIL("TIOCMGET ioctl failed");

It looks like OS X just doesn't like PTYs.

What do you think?

jimbojsb commented 9 years ago

I had assumed as much. I'll pull your changes and make another pass with all the variations I've attempted and see if I can make it work.

On Sat, Jan 10, 2015 at 5:06 PM, Michael Phan-Ba notifications@github.com wrote:

Hi @jimbojsb https://github.com/jimbojsb, thank you for the bug report!

I added the SetDebug method to enable debugging in libserialport:

serial.SetDebug(true)

I also pushed some changes I hadn't committed to support RTS/CTS and DTR/DSR directly.

Here's the output after enabling internal debugging:

sp_set_debug_handler returning. sp_get_port_by_name(/dev/ttys003, 0xc208018e30) called. Building structure for port /dev/ttys003. Getting serial port list. Iterating over results. get_port_details returning SP_OK. sp_get_port_by_name returning SP_OK. sp_copy_port(0x4700010, 0xc208040190) called. Copying port structure. sp_get_port_by_name(/dev/ttys003, 0xc208040190) called. Building structure for port /dev/ttys003. Getting serial port list. Iterating over results. get_port_details returning SP_OK. sp_get_port_by_name returning SP_OK. sp_copy_port returning 0. sp_open(0x4700070, 0x1) called. Opening port /dev/ttys003. get_config(0x4700070, 0x7fff5fbff800, 0x7fff5fbff7d8) called. Getting configuration for port /dev/ttys003. sp_last_error_message() called. sp_last_error_message returning Inappropriate ioctl for device. get_config returning SP_ERR_FAIL: TIOCMGET ioctl failed: Inappropriate ioctl for device. sp_free_error_message(Inappropriate ioctl for device) called. sp_free_error_message returning. sp_close(0x4700070) called. Closing port /dev/ttys003. sp_close returning SP_OK. sp_open returning SP_ERR_FAIL. sp_new_config(0xc2080401a0) called. sp_new_config returning SP_OK. sp_get_config(0x4700070, 0x4700100) called. sp_get_config returning SP_ERR_ARG: Invalid port fd.

I traced the error to serialport.c:1485:

if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0)
    RETURN_FAIL("TIOCMGET ioctl failed");

It looks like OS X just doesn't like PTYs.

What do you think?

— Reply to this email directly or view it on GitHub https://github.com/mikepb/go-serial/issues/1#issuecomment-69475952.

mikepb commented 9 years ago

If it helps, I also ran into similar issues and just ended up using stty and opening the port as a file. You don't get async semantics and can't set a break signal, but at least it's reliable.

https://github.com/mikepb/go-cuddlebot/blob/master/cuddle/port.go

jimbojsb commented 9 years ago

I poked around a bit more, it looks like TIOCMGET will never work with a PTY. I had issues with it under Linux too, just hadn't bothered trying it up to that point.