1
0
mirror of https://github.com/hybridgroup/gobot.git synced 2025-04-24 13:48:49 +08:00

go lint and documentation tweaks for the sysfs package

This commit is contained in:
Adrian Zankich 2014-12-31 06:12:25 -08:00
parent 8ea3ae2c8b
commit 22b84cc6ef
8 changed files with 55 additions and 25 deletions

View File

@ -8,18 +8,29 @@ import (
)
const (
IN = "in"
OUT = "out"
HIGH = 1
LOW = 0
// IN gpio direction
IN = "in"
// OUT gpio direction
OUT = "out"
// HIGH gpio level
HIGH = 1
// LOW gpio level
LOW = 0
// GPIOPATH default linux gpio path
GPIOPATH = "/sys/class/gpio"
)
// DigitalPin is the interface for sysfs gpio interactions
type DigitalPin interface {
// Unexport unexports the pin and releases the pin from the operating system
Unexport() error
// Export exports the pin for use by the operating system
Export() error
// Read reads the current value of the pin
Read() (int, error)
// Direction sets the direction for the pin
Direction(string) error
// Write writes to the pin
Write(int) error
}
@ -42,19 +53,16 @@ func NewDigitalPin(pin int, v ...string) DigitalPin {
return d
}
// Direction sets the direction for the pin
func (d *digitalPin) Direction(dir string) error {
_, err := writeFile(fmt.Sprintf("%v/%v/direction", GPIOPATH, d.label), []byte(dir))
return err
}
// Write writes to the pin
func (d *digitalPin) Write(b int) error {
_, err := writeFile(fmt.Sprintf("%v/%v/value", GPIOPATH, d.label), []byte(strconv.Itoa(b)))
return err
}
// Read reads the current value of the pin
func (d *digitalPin) Read() (n int, err error) {
buf, err := readFile(fmt.Sprintf("%v/%v/value", GPIOPATH, d.label))
if err != nil {
@ -63,7 +71,6 @@ func (d *digitalPin) Read() (n int, err error) {
return strconv.Atoi(string(buf[0]))
}
// Export exports the pin for use by the operating system
func (d *digitalPin) Export() error {
if _, err := writeFile(GPIOPATH+"/export", []byte(d.pin)); err != nil {
// If EBUSY then the pin has already been exported
@ -74,7 +81,6 @@ func (d *digitalPin) Export() error {
return nil
}
// Unexport unexports the pin and releases the pin from the operating system
func (d *digitalPin) Unexport() error {
if _, err := writeFile(GPIOPATH+"/unexport", []byte(d.pin)); err != nil {
// If EINVAL then the pin is reserved in the system and can't be unexported

View File

@ -4,6 +4,7 @@ import (
"os"
)
// A File represents basic IO interactions with the underlying file system
type File interface {
Write(b []byte) (n int, err error)
WriteString(s string) (ret int, err error)
@ -14,26 +15,28 @@ type File interface {
Close() error
}
// Filesystem opens files and returns either a native file system or user defined
type Filesystem interface {
OpenFile(name string, flag int, perm os.FileMode) (file File, err error)
}
// Filesystem that opens real files on the host.
// NativeFilesystem represents the native file system implementation
type NativeFilesystem struct{}
// Default to the host filesystem.
var fs Filesystem = &NativeFilesystem{}
// Override the default filesystem.
// SetFilesystem sets the filesystem implementation.
func SetFilesystem(f Filesystem) {
fs = f
}
// OpenFile calls os.OpenFile().
func (fs *NativeFilesystem) OpenFile(name string, flag int, perm os.FileMode) (file File, err error) {
return os.OpenFile(name, flag, perm)
}
// Open a file the same as os.OpenFile().
// OpenFile calls either the NativeFilesystem or user defined OpenFile
func OpenFile(name string, flag int, perm os.FileMode) (file File, err error) {
return fs.OpenFile(name, flag, perm)
}

View File

@ -6,13 +6,16 @@ import (
"time"
)
// A mock filesystem of simple files.
var _ File = (*MockFile)(nil)
var _ Filesystem = (*MockFilesystem)(nil)
// MockFilesystem represents a filesystem of mock files.
type MockFilesystem struct {
Seq int // Increases with each write or read.
Files map[string]*MockFile
}
// A simple mock file that contains a single string. Any write
// A MockFile represents a mock file that contains a single string. Any write
// overwrites, and any read returns from the start.
type MockFile struct {
Contents string
@ -24,23 +27,24 @@ type MockFile struct {
fs *MockFilesystem
}
var _ File = (*MockFile)(nil)
var _ Filesystem = (*MockFilesystem)(nil)
// Write writes string(b) to f.Contents
func (f *MockFile) Write(b []byte) (n int, err error) {
return f.WriteString(string(b))
}
// WriteString writes s to f.Contents
func (f *MockFile) WriteString(s string) (ret int, err error) {
f.Contents = s
f.Seq = f.fs.next()
return len(s), nil
}
// Sync implements the File interface Sync function
func (f *MockFile) Sync() (err error) {
return nil
}
// Read copies b bytes from f.Contents
func (f *MockFile) Read(b []byte) (n int, err error) {
count := len(b)
if len(f.Contents) < count {
@ -52,18 +56,22 @@ func (f *MockFile) Read(b []byte) (n int, err error) {
return count, nil
}
// ReadAt calls MockFile.Read
func (f *MockFile) ReadAt(b []byte, off int64) (n int, err error) {
return f.Read(b)
}
// Fd returns a random uintprt based on the time of the MockFile creation
func (f *MockFile) Fd() uintptr {
return f.fd
}
// Close implements the File interface Close function
func (f *MockFile) Close() error {
return nil
}
// NewMockFilesystem returns a new MockFilesystem given a list of file paths
func NewMockFilesystem(files []string) *MockFilesystem {
m := &MockFilesystem{
Files: make(map[string]*MockFile),
@ -76,17 +84,18 @@ func NewMockFilesystem(files []string) *MockFilesystem {
return m
}
// OpenFile opens file name from fs.Files, if the file does not exist it returns an os.PathError
func (fs *MockFilesystem) OpenFile(name string, flag int, perm os.FileMode) (file File, err error) {
f, ok := fs.Files[name]
if ok {
f.Opened = true
f.Closed = false
return f, nil
} else {
return (*MockFile)(nil), &os.PathError{Err: errors.New(name + ": No such file.")}
}
return (*MockFile)(nil), &os.PathError{Err: errors.New(name + ": No such file.")}
}
// Add adds a new file to fs.Files given a name, and returns the newly created file
func (fs *MockFilesystem) Add(name string) *MockFile {
f := &MockFile{
Seq: -1,

View File

@ -1,8 +1,9 @@
package sysfs
import (
"github.com/hybridgroup/gobot"
"testing"
"github.com/hybridgroup/gobot"
)
func TestMockFilesystemOpen(t *testing.T) {

View File

@ -1,9 +1,10 @@
package sysfs
import (
"github.com/hybridgroup/gobot"
"os"
"testing"
"github.com/hybridgroup/gobot"
)
func TestFilesystemOpen(t *testing.T) {

View File

@ -1,16 +1,17 @@
package sysfs
import (
"errors"
"fmt"
"io"
"os"
"syscall"
)
// I2CSlave is the linux default ioctrl request code
const I2CSlave = 0x0703
// NewI2cDevice creates a new io.ReadWriteCloser with the proper ioctrl given an i2c bus location and device address
// NewI2cDevice returns an io.ReadWriteCloser with the proper ioctrl given
// an i2c bus location and device address
func NewI2cDevice(location string, address byte) (io.ReadWriteCloser, error) {
file, err := OpenFile(location, os.O_RDWR, os.ModeExclusive)
@ -26,7 +27,7 @@ func NewI2cDevice(location string, address byte) (io.ReadWriteCloser, error) {
)
if errno != 0 {
return nil, errors.New(fmt.Sprintf("Failed with syscall.Errno %v", errno))
return nil, fmt.Errorf("Failed with syscall.Errno %v", errno)
}
return file, nil

View File

@ -1,10 +1,11 @@
package sysfs
import (
"github.com/hybridgroup/gobot"
"io"
"os"
"testing"
"github.com/hybridgroup/gobot"
)
func TestNewI2cDevice(t *testing.T) {

View File

@ -4,27 +4,35 @@ import (
"syscall"
)
// SystemCaller represents a Syscall
type SystemCaller interface {
Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
}
// NativeSyscall represents the native Syscall
type NativeSyscall struct{}
// MockSyscall represents the mock Syscall
type MockSyscall struct{}
var sys SystemCaller = &NativeSyscall{}
// SetSyscall sets the Syscall implementation
func SetSyscall(s SystemCaller) {
sys = s
}
// Syscall calls either the NativeSyscall or user defined Syscall
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
return sys.Syscall(trap, a1, a2, a3)
}
// Syscall calls syscall.Syscall
func (sys *NativeSyscall) Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
return syscall.Syscall(trap, a1, a2, a3)
}
// Syscall implements the SystemCaller interface
func (sys *MockSyscall) Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
return 0, 0, 0
}