Added first draft of documentation

This commit is contained in:
Cristian Maglie
2015-01-02 03:08:31 +01:00
parent 20bc06bd0e
commit 55b609d095
4 changed files with 128 additions and 41 deletions

85
doc.go Normal file
View File

@@ -0,0 +1,85 @@
//
// Copyright 2014 Cristian Maglie. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
/*
This is a cross-platform serial library for go.
The canonical import for this library is go.bug.st/serial so the import line
is the following:
import "go.bug.st/serial"
It is possibile to get the list of available serial ports with the
GetPortsList function:
ports, err := serial.GetPortsList()
if err != nil {
log.Fatal(err)
}
if len(ports) == 0 {
log.Fatal("No serial ports found!")
}
for _, port := range ports {
fmt.Printf("Found port: %v\n", port)
}
The serial port can be opened with the OpenPort function:
mode := &serial.Mode{
BaudRate: 115200,
}
port, err := serial.OpenPort("/dev/ttyUSB0", mode)
if err != nil {
log.Fatal(err)
}
The OpenPort command needs a "mode" parameter that specifies the configuration
options for the serial port. If not specified the default options are 9600_N81,
in the example above only the speed is changed so the port is opened using 115200_N81.
The following snippets shows how to declare a configuration for 57600_E71:
mode := &serial.Mode{
BaudRate: 57600,
Parity: serial.PARITY_EVEN,
DataBits: 7,
StopBits: serial.STOPBITS_ONE,
}
The configuration can be changed at any time with the SetMode function:
err := port.SetMode(mode)
if err != nil {
log.Fatal(err)
}
The port object implements the io.ReadWriteCloser interface, so we can use
the usual Read, Write and Close functions to send and receive data from the
serial port:
n, err := port.Write([]byte("10,20,30\n\r"))
if err != nil {
log.Fatal(err)
}
fmt.Printf("Sent %v bytes\n", n)
buff := make([]byte, 100)
for {
n, err := port.Read(buff)
if err != nil {
log.Fatal(err)
break
}
if n == 0 {
fmt.Println("\nEOF")
break
}
fmt.Printf("%v", string(buff[:n]))
}
This library doesn't make use of cgo and "C" package, so it's a pure go library
that can be easily cross compiled.
*/
package serial // import "go.bug.st/serial"

View File

@@ -6,39 +6,30 @@
package serial // import "go.bug.st/serial" package serial // import "go.bug.st/serial"
import "io" // This structure describes a serial port configuration.
// SerialPort object
type SerialPort interface {
io.ReadWriteCloser
// Set all parameters together
SetMode(mode *Mode) error
}
type Mode struct { type Mode struct {
BaudRate int BaudRate int // The serial port bitrate (aka Baudrate)
DataBits int DataBits int // Size of the character (must be 5, 6, 7 or 8)
Parity Parity Parity Parity // Parity (see Parity type for more info)
StopBits StopBits StopBits StopBits // Stop bits (see StopBits type for more info)
} }
type Parity int type Parity int
const ( const (
PARITY_NONE Parity = iota PARITY_NONE Parity = iota // No parity (default)
PARITY_ODD PARITY_ODD // Odd parity
PARITY_EVEN PARITY_EVEN // Even parity
PARITY_MARK PARITY_MARK // Mark parity (always 1)
PARITY_SPACE PARITY_SPACE // Space parity (always 0)
) )
type StopBits int type StopBits int
const ( const (
STOPBITS_ONE StopBits = iota STOPBITS_ONE StopBits = iota // 1 Stop bit
STOPBITS_ONEPOINTFIVE STOPBITS_ONEPOINTFIVE // 1.5 Stop bits
STOPBITS_TWO STOPBITS_TWO // 2 Stop bits
) )
// Platform independent error type for serial ports // Platform independent error type for serial ports

View File

@@ -14,25 +14,35 @@ import "strings"
import "syscall" import "syscall"
import "unsafe" import "unsafe"
// opaque type that implements SerialPort interface for linux // Opaque type that implements SerialPort interface for linux
type unixSerialPort struct { type SerialPort struct {
handle int handle int
} }
func (port *unixSerialPort) Close() error { // Close the serial port
func (port *SerialPort) Close() error {
port.releaseExclusiveAccess() port.releaseExclusiveAccess()
return syscall.Close(port.handle) return syscall.Close(port.handle)
} }
func (port *unixSerialPort) Read(p []byte) (n int, err error) { // Stores data received from the serial port into the provided byte array
// buffer. The function returns the number of bytes read.
//
// The Read function blocks until (at least) one byte is received from
// the serial port or an error occurs.
func (port *SerialPort) Read(p []byte) (n int, err error) {
return syscall.Read(port.handle, p) return syscall.Read(port.handle, p)
} }
func (port *unixSerialPort) Write(p []byte) (n int, err error) { // Send the content of the data byte array to the serial port.
// Returns the number of bytes written.
func (port *SerialPort) Write(p []byte) (n int, err error) {
return syscall.Write(port.handle, p) return syscall.Write(port.handle, p)
} }
func (port *unixSerialPort) SetMode(mode *Mode) error { // Set all parameters of the serial port. See the Mode structure for more
// info.
func (port *SerialPort) SetMode(mode *Mode) error {
settings, err := port.getTermSettings() settings, err := port.getTermSettings()
if err != nil { if err != nil {
return err return err
@@ -52,7 +62,8 @@ func (port *unixSerialPort) SetMode(mode *Mode) error {
return port.setTermSettings(settings) return port.setTermSettings(settings)
} }
func OpenPort(portName string, mode *Mode) (SerialPort, error) { // Open the serial port using the specified modes
func OpenPort(portName string, mode *Mode) (*SerialPort, error) {
h, err := syscall.Open(portName, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NDELAY, 0) h, err := syscall.Open(portName, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NDELAY, 0)
if err != nil { if err != nil {
switch err { switch err {
@@ -63,7 +74,7 @@ func OpenPort(portName string, mode *Mode) (SerialPort, error) {
} }
return nil, err return nil, err
} }
port := &unixSerialPort{ port := &SerialPort{
handle: h, handle: h,
} }
@@ -219,20 +230,20 @@ func setRawMode(settings *syscall.Termios) {
// native syscall wrapper functions // native syscall wrapper functions
func (port *unixSerialPort) getTermSettings() (*syscall.Termios, error) { func (port *SerialPort) getTermSettings() (*syscall.Termios, error) {
settings := &syscall.Termios{} settings := &syscall.Termios{}
err := ioctl(port.handle, ioctl_tcgetattr, uintptr(unsafe.Pointer(settings))) err := ioctl(port.handle, ioctl_tcgetattr, uintptr(unsafe.Pointer(settings)))
return settings, err return settings, err
} }
func (port *unixSerialPort) setTermSettings(settings *syscall.Termios) error { func (port *SerialPort) setTermSettings(settings *syscall.Termios) error {
return ioctl(port.handle, ioctl_tcsetattr, uintptr(unsafe.Pointer(settings))) return ioctl(port.handle, ioctl_tcsetattr, uintptr(unsafe.Pointer(settings)))
} }
func (port *unixSerialPort) acquireExclusiveAccess() error { func (port *SerialPort) acquireExclusiveAccess() error {
return ioctl(port.handle, syscall.TIOCEXCL, 0) return ioctl(port.handle, syscall.TIOCEXCL, 0)
} }
func (port *unixSerialPort) releaseExclusiveAccess() error { func (port *SerialPort) releaseExclusiveAccess() error {
return ioctl(port.handle, syscall.TIOCNXCL, 0) return ioctl(port.handle, syscall.TIOCNXCL, 0)
} }

View File

@@ -19,7 +19,7 @@ package serial // import "go.bug.st/serial"
import "syscall" import "syscall"
// opaque type that implements SerialPort interface for Windows // opaque type that implements SerialPort interface for Windows
type windowsSerialPort struct { type SerialPort struct {
Handle syscall.Handle Handle syscall.Handle
} }
@@ -56,11 +56,11 @@ func GetPortsList() ([]string, error) {
return list, nil return list, nil
} }
func (port *windowsSerialPort) Close() error { func (port *SerialPort) Close() error {
return syscall.CloseHandle(port.Handle) return syscall.CloseHandle(port.Handle)
} }
func (port *windowsSerialPort) Read(p []byte) (int, error) { func (port *SerialPort) Read(p []byte) (int, error) {
var readed uint32 var readed uint32
params := &DCB{} params := &DCB{}
for { for {
@@ -83,7 +83,7 @@ func (port *windowsSerialPort) Read(p []byte) (int, error) {
} }
} }
func (port *windowsSerialPort) Write(p []byte) (int, error) { func (port *SerialPort) Write(p []byte) (int, error) {
var writed uint32 var writed uint32
err := syscall.WriteFile(port.Handle, p, &writed, nil) err := syscall.WriteFile(port.Handle, p, &writed, nil)
return int(writed), err return int(writed), err
@@ -171,7 +171,7 @@ const (
TWOSTOPBITS = 2 TWOSTOPBITS = 2
) )
func (port *windowsSerialPort) SetMode(mode *Mode) error { func (port *SerialPort) SetMode(mode *Mode) error {
params := DCB{} params := DCB{}
if GetCommState(port.Handle, &params) != nil { if GetCommState(port.Handle, &params) != nil {
port.Close() port.Close()
@@ -196,7 +196,7 @@ func (port *windowsSerialPort) SetMode(mode *Mode) error {
return nil return nil
} }
func OpenPort(portName string, mode *Mode) (SerialPort, error) { func OpenPort(portName string, mode *Mode) (*SerialPort, error) {
portName = "\\\\.\\" + portName portName = "\\\\.\\" + portName
path, err := syscall.UTF16PtrFromString(portName) path, err := syscall.UTF16PtrFromString(portName)
if err != nil { if err != nil {
@@ -219,7 +219,7 @@ func OpenPort(portName string, mode *Mode) (SerialPort, error) {
return nil, err return nil, err
} }
// Create the serial port // Create the serial port
port := &windowsSerialPort{ port := &SerialPort{
Handle: handle, Handle: handle,
} }