sers

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 18, 2019 License: MIT Imports: 8 Imported by: 6

README

sers

Overview

Package sers offers serial port access for the Go programming language. It is a stated goal of this project to allow for configuration of non-traditional bit rates as the may be useful in a wide range of embedded projects.

Functionality

Primarily the library provides an implementation of the SerialPort interface for the supported platforms. For every serial port, you get the functionality of an io.ReadWriteCloser as well as methods to set and query various parameters. Secondarily it helps you communicate with the users of your programs through the use of mode strings that represent the data than can be written and read with {Get,Set}Mode.

The SetMode() and GetMode() methods allow setting and retrieving key parameters such as baud rate, number of data bits, number of stop bits and the used parity scheme. As far as the underlying platforms support it, SetMode allows you to set arbitrary, non-traditional baud rate. The generation of break conditions is supported through the SetBreak() method. The behavior of the Read() method can be fine tuned with the SetReadParams() method.

The library offers the concept of mode strings like 9600,7e1 or 57600,8n1,rtscts. These can be parsed by ParseModestring into an internal representation that can be set through SetModeStruct. The mode string is quite flexible and allows omission of certain parts. Mode strings are easily read and written by humans. This makes the user interface of programs that use serial ports easier to create and use: programs do not need to provide a plethora of command line switches, but can accept one string and delegate handling to sers.

Due to backwards compatibility there is a difference in data representation between SetMode and GetMode.

Platforms

sers has been successfully used on Mac OS X, Linux and Windows.

The following known restrictions apply.

Linux
  • cgo is needed to compile sers
  • Using non-traditional baud rates may not work. This depends on whether the system headers have correct definitions for struct termios2. Traditional baud rates use traditional termios baud rate setting methods via defines such as B1200 etc. The author is successfully using non-traditional baud rates on Linux, though.
OS X
  • Calling GetMode before having called SetMode will result in an error.
  • cgo is needed to compile sers
Windows
  • Only NO_HANDSHAKE is supported.

Feature ideas

Not relying on cgo

Compilation for Linux and OS X involved use of cgo and thus a C compiler. This makes cross compilation harder for every user of sers.

If all necessary definitions for serial port handling can be expressed in Go, it is conceivable to make a pure-Go version for both these operation systems.

Deadlines

Adding deadline methods, SetDeadline as well as Set{Read,Write}Deadline.

On termios platforms this relatively easy as we can let the runtime netpoller do the heavy lifting. On Windows I do not yet understand the most promising path to implementation.

net.Conn support

Building on deadlines, {Local,Remote}Addr methods would enable a SerialPort to implement net.Conn. This makes it easy to plug a SerialPort into various network protocol implementations that build on byte streams.

Regularize interface

With a working deadline implementation, the wart of SetReadParams could be dropped or, at least, relegated to platform specific support. {Get,Set}Mode can be made to both take a Mode struct. Representation of parity, stop bit and handshake settings will be move to their own type to prevent mixups.

These changes would mean a new major version as they imply modifications that are not backwards compatible.

Release History

v1.1.0
  • add GetMode() to SerialPort
  • add modestrings, ParseModestring
  • add Mode struct
  • add a more detailed README.md
v1.0.2
  • termios platofrms: make Close() unblock readers
v1.0.1
  • use our own definition of struct termios2 as the headers on a number of linux distributions are wrong.
  • add verification/setbaudrate
v1.0.0

sers appears in the primordial soup.

Documentation

Overview

Package sers offers serial port access. It is a stated goal of this package to allow for non-standard bit rates as the may be useful in a wide range of embedded projects.

Example

This program opens a serial port, configurable by changing portname below and configures it for 57600 baud, 8 data bits, no parity bit, 1 stop bit, no handshaking. It then reads up to 128 bytes from the serial port, with a timeout of 1 second and prints the received bytes to stdout.

package main

import (
	"encoding/hex"
	"fmt"
	"log"

	"github.com/distributed/sers"
)

// This program opens a serial port, configurable by changing portname
// below and configures it for 57600 baud, 8 data bits, no parity bit,
// 1 stop bit, no handshaking. It then reads up to 128 bytes from the serial
// port, with a timeout of 1 second and prints the received
// bytes to stdout.
func main() {
	portname := "/dev/ttyUSB0"
	rb, err := readFirstBytesFromPort(portname)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("got %d bytes from %s:\n%s", len(rb), portname,
		hex.Dump(rb))
}

func readFirstBytesFromPort(fn string) ([]byte, error) {
	sp, err := sers.Open(fn)
	if err != nil {
		return nil, err
	}
	defer sp.Close()

	// 57600 baud, 8 data bits, no parity bit, 1 stop bit
	// no handshake. non-standard baud rates are possible.
	err = sp.SetMode(57600, 8, sers.N, 1, sers.NO_HANDSHAKE)
	if err != nil {
		return nil, err
	}

	// setting:
	// minread = 0: minimal buffering on read, return characters as early as possible
	// timeout = 1.0: time out if after 1.0 seconds nothing is received
	err = sp.SetReadParams(0, 1.0)
	if err != nil {
		return nil, err
	}

	var rb [128]byte
	n, err := sp.Read(rb[:])

	return rb[:n], err
}
Output:

Index

Examples

Constants

View Source
const (
	N = 0 // no parity
	E = 1 // even parity
	O = 2 // odd parity
)
View Source
const (
	NO_HANDSHAKE     = 0
	RTSCTS_HANDSHAKE = 1
)

Variables

This section is empty.

Functions

func SetModeStruct added in v1.1.0

func SetModeStruct(sp SerialPort, mode Mode) error

Types

type Error

type Error struct {
	Operation       string
	UnderlyingError error
}

func (*Error) Error

func (e *Error) Error() string

type Mode added in v1.1.0

type Mode struct {
	Baudrate  int
	DataBits  int
	Parity    int
	Stopbits  int
	Handshake int
}

func ParseModestring added in v1.1.0

func ParseModestring(s string) (Mode, error)

Parses a modestring like "115200,8n1,rtscts" into a struct Mode. The format is baudrate,framestring,handshake. Either the handshake part or both the framestring and handshake parts can be omitted. For the omitted parts, defaults of 8 data bits, no parity, 1 stop bit and no handshaking will be filled in. The framestring consists of a sequence databits, parity, stopbits. Any or all of the three components can be left out. Non-specified parts will take the default values mentioned before.

Valid choices for databits are [5, 6, 7, 8], for parity it is [n, o, e] and for stopbits it's [1, 2]. Valid choices for the handshake parts are "", "none" and "rtscts". The function is not case sensitive.

A couple of examples:

60000	         - 60000 baud, 8 data bits, no parity, 1 stopbit, no handshake
115200,8e1       - 115200 baud, 8 data bits, even parity, 1 stopbit, no handshake
57600,8o1,rtscts - 57600 baud, 8 data bits, odd parity, 1 stopbit, rts/cts handshake
19200,72		 - 19200 baud, 7 data bits, no parity, 2 stop bits, no handshake
9600,2,rtscts    - 9600 baud, 8 data bits, no parity, 2 stop bits, rts/cts handshake

func (Mode) String added in v1.1.0

func (m Mode) String() string

func (Mode) Valid added in v1.1.0

func (m Mode) Valid() bool

type ParameterError

type ParameterError struct {
	Parameter string
	Reason    string
}

func (*ParameterError) Error

func (pe *ParameterError) Error() string

type SerialPort

type SerialPort interface {
	io.Reader
	io.Writer
	io.Closer

	// SetMode sets the frame format and handshaking configuration.
	// baudrate may be freely chosen, the driver is allowed to reject
	// unachievable baud rates. databits may be any number of data bits
	// supported by the driver. parity is one of (N|O|E) for none, odd
	// or even parity. handshake is either NO_HANDSHAKE or
	// RTSCTS_HANDSHAKE.
	//
	// Known bug on Windows: Only NO_HANDSHAKE is supported.
	SetMode(baudrate, databits, parity, stopbits, handshake int) error

	// GetMode retrieves the current mode settings.
	//
	// Known bug on OS X: GetMode only works after SetMode has been called
	// before. If not, it returns an error.
	GetMode() (Mode, error)

	// SetReadParams sets the minimum number of bytes to read and a read
	// timeout in seconds. These parameters roughly correspond to the
	// UNIX termios concepts of VMIN and VTIME.
	SetReadParams(minread int, timeout float64) error

	// SetBreak turns on the generation of a break condition if on == true,
	// otherwise it clear the break condition.
	SetBreak(on bool) error
}

Serialport represents a serial port and offers configuration of baud rate, frame format, handshaking and read paramters as well as setting and clearing break conditions.

func Open

func Open(fn string) (SerialPort, error)

func TakeOver

func TakeOver(f *os.File) (SerialPort, error)

TakeOver accepts an open *os.File and returns a SerialPort representing the open file.

Attention: This calls the .Fd() method of the *os.File and thus renders the deadline functionality unusable. Furthermore blocked readers may remain stuck after a Close() if no data arrives.

type StringError

type StringError string

func (StringError) Error

func (se StringError) Error() string

Directories

Path Synopsis
verification

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL