mirror of
https://github.com/hybridgroup/gobot.git
synced 2025-04-26 13:48:49 +08:00
go lint and documentation tweaks for the sysfs package
This commit is contained in:
parent
8ea3ae2c8b
commit
22b84cc6ef
@ -8,18 +8,29 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// 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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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.")}
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
|
@ -1,8 +1,9 @@
|
||||
package sysfs
|
||||
|
||||
import (
|
||||
"github.com/hybridgroup/gobot"
|
||||
"testing"
|
||||
|
||||
"github.com/hybridgroup/gobot"
|
||||
)
|
||||
|
||||
func TestMockFilesystemOpen(t *testing.T) {
|
||||
|
@ -1,9 +1,10 @@
|
||||
package sysfs
|
||||
|
||||
import (
|
||||
"github.com/hybridgroup/gobot"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hybridgroup/gobot"
|
||||
)
|
||||
|
||||
func TestFilesystemOpen(t *testing.T) {
|
||||
|
@ -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
|
||||
|
@ -1,10 +1,11 @@
|
||||
package sysfs
|
||||
|
||||
import (
|
||||
"github.com/hybridgroup/gobot"
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hybridgroup/gobot"
|
||||
)
|
||||
|
||||
func TestNewI2cDevice(t *testing.T) {
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user