gpiod

package module
v0.0.0-...-f0d707b Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2022 License: MIT Imports: 10 Imported by: 0

README

gpiod

Build Status PkgGoDev Go Report Card

A native Go library for Linux GPIO.

gpiod is a library for accessing GPIO pins/lines on Linux platforms using the GPIO character device.

The goal of this library is to provide the Go equivalent of the C libgpiod library. The intent is not to mirror the libgpiod API but to provide the equivalent functionality.

⚠ v0.6.0 introduces a few API breaking changes. Refer to the release notes if updating from an older version.

Features

Supports the following functionality per line and for collections of lines:

  • direction (input/output)1
  • write (active/inactive)
  • read (active/inactive)
  • active high/low (defaults to high)
  • output mode (push-pull/open-drain/open-source)
  • pull up/down2
  • watches and edge detection (rising/falling/both)
  • chip and line labels
  • debouncing input lines3
  • different configurations for lines within a collection3

1 Dynamically changing line direction without releasing the line requires Linux v5.5 or later.

2 Requires Linux v5.5 or later.

3 Requires Linux v5.10 or later.

All library functions are safe to call from different goroutines.

Quick Start

A simple piece of wire example that reads the value of an input line (pin 2) and writes its value to an output line (pin 3):

import "github.com/warthog618/gpiod"

...

in, _ := gpiod.RequestLine("gpiochip0", 2, gpiod.AsInput)
val, _ := in.Value()
out, _ := gpiod.RequestLine("gpiochip0", 3, gpiod.AsOutput(val))

...

Error handling and releasing of resources omitted for brevity.

Usage

import "github.com/warthog618/gpiod"

Error handling is omitted from the following examples for brevity.

Line Requests

To read or alter the value of a line it must first be requested using gpiod.RequestLine:

l, _ := gpiod.RequestLine("gpiochip0", 4)   // in its existing state

or from the Chip object using Chip.RequestLine:

l, _ := c.RequestLine(4)                    // from a Chip object

The offset parameter identifies the line on the chip, and is specific to the GPIO chip. To improve readability, convenience mappings can be provided for specific devices, such as the Raspberry Pi:

l, _ := c.RequestLine(rpi.J8p7)             // using Raspberry Pi J8 mapping

The initial configuration of the line can be set by providing line configuration options, as shown in this AsOutput example:

l, _ := gpiod.RequestLine("gpiochip0", 4, gpiod.AsOutput(1))  // as an output line

Multiple lines from the same chip may be requested as a collection of lines using gpiod.RequestLines

ll, _ := gpiod.RequestLines("gpiochip0", []int{0, 1, 2, 3}, gpiod.AsOutput(0, 0, 1, 1))

or from a Chip object using Chip.RequestLines:

ll, _ := c.RequestLines([]int{0, 1, 2, 3}, gpiod.AsOutput(0, 0, 1, 1))

When no longer required, the line(s) should be closed to release resources:

l.Close()
ll.Close()
Line Values

Lines must be requsted using RequestLine before their values can be accessed.

Read Input

The current line value can be read with the Value method:

r, _ := l.Value()  // Read state from line (active / inactive)

For collections of lines, the level of all lines is read simultaneously using the Values method:

rr := []int{0, 0, 0, 0} // buffer to read into...
ll.Values(rr)           // Read the state of a collection of lines
Write Output

The current line value can be set with the SetValue method:

l.SetValue(1)     // Set line active
l.SetValue(0)     // Set line inactive

Also refer to the blinker example.

For collections of lines, all lines are set simultaneously using the SetValues method:

ll.SetValues([]int{0, 1, 0, 1}) // Set a collection of lines
Edge Watches

The value of an input line can be watched and trigger calls to handler functions.

The watch can be on rising or falling edges, or both.

The events are passed to a handler function provided using the WithEventHandler(eh) option. The handler function is passed a LineEvent, which contains details of the edge event including the offset of the triggering line, the time the edge was detected and the type of edge detected:

func handler(evt gpiod.LineEvent) {
  // handle edge event
}

l, _ = c.RequestLine(rpi.J8p7, gpiod.WithEventHandler(handler), gpiod.WithBothEdges)

To maintain event ordering, the event handler is called serially from a goroutine that reads the events from the kernel. The event handler is expected to be short lived, and so should hand off any potentially blocking operations to a separate goroutine.

An edge watch can be removed by closing the line:

l.Close()

or by reconfiguring the requested lines to disable edge detection:

l.Reconfigure(gpiod.WithoutEdges)

Note that the Close waits for the event handler to return and so must not be called from the event handler context - it should be called from a separate goroutine.

Also see the watcher example.

Line Configuration

Line configuration is set via options to Chip.RequestLine(s) and Line.Reconfigure. These override any default which may be set in NewChip.

Note that configuration options applied to a collection of lines apply to all lines in the collection, unless they are applied to a subset of the requested lines using the WithLines option.

Reconfiguration

Requested lines may be reconfigured using the Reconfigure method:

l.Reconfigure(gpiod.AsInput)            // set direction to Input
ll.Reconfigure(gpiod.AsOutput(1, 0))    // set direction to Output (and values to active and inactive)

The Line.Reconfigure method accepts differential changes to the configuration for the lines, so option categories not specified or overridden by the specified changes will remain unchanged.

The Line.Reconfigure method requires Linux v5.5 or later.

Complex Configurations

It is sometimes necessary for the configuration of lines within a request to have slightly different configurations. Line options may be applied to a subset of requested lines using the WithLines(offsets, options) option.

The following example requests a set of output lines and sets some of the lines in the request to active low:

ll, _ = c.RequestLines([]int{0, 1, 2, 3}, gpiod.AsOutput(0, 0, 1, 1),
    gpiod.WithLines([]int{0, 3}, gpiod.AsActiveLow),
    gpiod.AsOpenDrain)

The configuration of the subset of lines inherits the configuration of the request at the point the WithLines is invoked. Subsequent changes to the request configuration do not alter the configuration of the subset - in the example above, lines 0 and 3 will not be configured as open-drain.

Once a line's configuration has branched from the request configuration it can only be altered with WithLines options:

ll.Reconfigure(gpiod.WithLines([]int{0}, gpiod.AsActiveHigh))

or reset to the request configuration using the Defaulted option:

ll.Reconfigure(gpiod.WithLines([]int{3}, gpiod.Defaulted))

Complex configurations require Linux v5.10 or later.

Chip Initialization

The Chip object is used to discover details about avaialble lines and can be used to request lines from a GPIO chip.

A Chip object is constructed using the NewChip function.

c, _ := gpiod.NewChip("gpiochip0")

The parameter is the chip name, which corresponds to the name of the device in the /dev directory, so in this example /dev/gpiochip0.

The list of currently available GPIO chips is returned by the Chips function:

cc := gpiod.Chips()

Default attributes for Lines requested from the Chip can be set via configuration options to NewChip.

c, _ := gpiod.NewChip("gpiochip0", gpiod.WithConsumer("myapp"))

In this example the consumer label is defaulted to "myapp".

When no longer required, the chip should be closed to release resources:

c.Close()

Closing a chip does not close or otherwise alter the state of any lines requested from the chip.

Line Info

Info about a line can be read at any time from the chip using the LineInfo method:

inf, _ := c.LineInfo(4)
inf, _ := c.LineInfo(rpi.J8p7) // Using Raspberry Pi J8 mapping

Note that the line info does not include the value. The line must be requested from the chip to access the value.

Once requested, the line info can also be read from the line:

inf, _ := l.Info()
infs, _ := ll.Info()
Info Watches

Changes to the line info can be monitored by adding an info watch for the line:

func infoChangeHandler( evt gpiod.LineInfoChangeEvent) {
    // handle change in line info
}

inf, _ := c.WatchLineInfo(4, infoChangeHandler)

Note that the info watch does not monitor the line value (active or inactive) only its configuration. Refer to Edge Watches for monitoring line value.

An info watch can be cancelled by unwatching:

c.UnwatchLineInfo(4)

or by closing the chip.

Categories

Most line configuration options belong to one of the following categories:

  • Active Level
  • Direction
  • Bias
  • Drive
  • Debounce
  • Edge Detection
  • Event Clock

Only one option from each category may be applied. If multiple options from a category are applied then all but the last are ignored.

Active Level

The values used throughout the API for line values are the logical value, which is 0 for inactive and 1 for active. The physical value considered active can be controlled using the AsActiveHigh and AsActiveLow options:

l, _ := c.RequestLine(4, gpiod.AsActiveLow) // during request
l.Reconfigure(gpiod.AsActiveHigh)           // once requested

Lines are typically active high by default.

Direction

The line direction can be controlled using the AsInput and AsOutput options:

l, _ := c.RequestLine(4, gpiod.AsInput) // during request
l.Reconfigure(gpiod.AsInput)            // set direction to Input
l.Reconfigure(gpiod.AsOutput(0))        // set direction to Output (and value to inactive)
Bias

The bias options control the pull up/down state of the line:

l, _ = c.RequestLine(4, gpiod.WithPullUp) // during request
l.Reconfigure(gpiod.WithBiasDisabled)     // once requested

The bias options require Linux v5.5 or later.

Drive

The drive options control how an output line is driven when active and inactive:

l,_ := c.RequestLine(4, gpiod.AsOpenDrain) // during request
l.Reconfigure(gpiod.AsOpenSource)          // once requested

The default drive for output lines is push-pull, which actively drives the line in both directions.

Debounce

Input lines may be debounced using the WithDebounce option. The debouncing will be performed by the underlying hardware, if supported, else by the Linux kernel.

period := 10 * time.Millisecond
l, _ = c.RequestLine(4, gpiod.WithDebounce(period))// during request
l.Reconfigure(gpiod.WithDebounce(period))         // once requested

The WithDebounce option requires Linux v5.10 or later.

Edge Detection

The edge options control which edges on input lines will generate edge events. Edge events are passed to the event handler specified in the WithEventHandler(eh) option.

By default edge detection is not enabled on requested lines.

Refer to Edge Watches for examples of the edge detection options.

Event Clock

The event clock options control the source clock used to timestamp edge events. This is only useful for Linux kernels v5.11 and later - prior to that the clock source is fixed.

The event clock source used by the kernel has changed over time as follows:

Kernel Version Clock source
pre-v5.7 CLOCK_REALTIME
v5.7 - v5.10 CLOCK_MONOTONIC
v5.11 and later configurable

Determining which clock the edge event timestamps contain is currently left as an exercise for the user.

Configuration Options

The available configuration options are:

Option Category Description
WithConsumer1 Info Set the consumer label for the lines
AsActiveLow Level Treat a low physical line value as active
AsActiveHigh Level Treat a high physical line value as active (default)
AsInput Direction Request lines as input
AsIs2 Direction Request lines in their current input/output state (default)
AsOutput(<values>...)3 Direction Request lines as output with the provided values
AsPushPull Drive Request output lines drive both high and low (default)
AsOpenDrain Drive Request lines as open drain outputs
AsOpenSource Drive Request lines as open source outputs
WithEventHandler(eh)1 Send edge events detected on requested lines to the provided handler
WithEventBufferSize(num)1,5 Suggest the minimum number of events that can be stored in the kernel event buffer for the requested lines
WithFallingEdge Edge Detection3 Request lines with falling edge detection
WithRisingEdge Edge Detection3 Request lines with rising edge detection
WithBothEdges Edge Detection3 Request lines with rising and falling edge detection
WithoutEdges5 Edge Detection3 Request lines with edge detection disabled (default)
WithBiasAsIs Bias4 Request the lines have their bias setting left unaltered (default)
WithBiasDisabled Bias4 Request the lines have internal bias disabled
WithPullDown Bias4 Request the lines have internal pull-down enabled
WithPullUp Bias4 Request the lines have internal pull-up enabled
WithDebounce(period)5 Debounce Request the lines be debounced with the provided period
WithMonotonicEventClock Event Clock Request the timestamp in edge events use the monotonic clock (default)
WithRealtimeEventClock6 Event Clock Request the timestamp in edge events use the realtime clock
WithLines(offsets, options...)3,5 Specify configuration options for a subset of lines in a request
Defaulted5 Reset the configuration for a request to the default configuration, or the configuration of a particular line in a request to the default for that request

The options described as default are generally not required, except to override other options earlier in a chain of configuration options.

1 Can be applied to either NewChip or Chip.RequestLine, but cannot be used with Line.Reconfigure.

2 Can be applied to Chip.RequestLine, but cannot be used with NewChip or Line.Reconfigure.

3 Can be applied to either Chip.RequestLine or Line.Reconfigure, but cannot be used with NewChip.

4 Requires Linux v5.5 or later.

5 Requires Linux v5.10 or later.

6 Requires Linux v5.11 or later.

Installation

On Linux:

go get github.com/warthog618/gpiod

For other platforms, where you intend to cross-compile for Linux, don't attempt to compile the package when it is installed:

go get -d github.com/warthog618/gpiod

Tools

A command line utility, gpiodctl, can be found in the cmd directory and is provided to allow manual or scripted manipulation of GPIO lines. This utility combines the Go equivalent of all the libgpiod command line tools into a single tool.

gpiodctl is a utility to control GPIO lines on Linux GPIO character devices

Usage:
  gpiodctl [flags]
  gpiodctl [command]

Available Commands:
  detect      Detect available GPIO chips
  find        Find a GPIO line by name
  get         Get the state of a line or lines
  help        Help about any command
  info        Info about chip lines
  mon         Monitor the state of a line or lines
  set         Set the state of a line or lines
  version     Display the version
  watch       Watch lines for changes to the line info

Flags:
  -h, --help   help for gpiodctl

Use "gpiodctl [command] --help" for more information about a command.

The Go equivalent of each of the libgpiod command line tools can also be found in the cmd directory.

Those tools are:

Tool Description
gpiodetect Report all the gpiochips available on the system.
gpioinfo Report the details of all the lines available on gpiochips.
gpiofind Find the gpiochip and offset of a line by name.
gpioget Get the value of a line or a set of lines on one gpiochip.
gpioset Set of value of a line or a set of lines on one gpiochip.
gpiomon Report edges detected on a line or set of lines on one gpiochip.

Tests

The library is fully tested, other than some error cases and sanity checks that are difficult to trigger.

The tests require a kernel release 5.1.0 or later to run. For all the tests to pass a kernel 5.5.0 or later is required.

The test user must have access to the /dev/gpiochip0 character device.

Platforms

The tests can be run on either of two platforms:

  • gpio-mockup (default)
  • Raspberry Pi
gpio-mockup

The gpio-mockup platform is any Linux platform with a recent kernel that supports the gpio-mockup loadable module. gpio-mockup must be built as a module and the test user must have rights to load and unload the module.

The gpio-mockup is the default platform for tests and benchmarks as it does not interact with physical hardware and so is always safe to run.

Raspberry Pi

On Raspberry Pi, the tests are intended to be run on a board with J8 pins 11 and 12 floating and with pins 15 and 16 tied together, possibly using a jumper across the header.

⚠ The tests set J8 pins 11, 12 and 16 to outputs so DO NOT run them on hardware where any of those pins is being externally driven.

The Raspberry Pi platform is selected by specifying the platform parameter on the test command line:

go test -platform=rpi

Tests have been run successfully on Raspberry Pi Zero W and Pi 4B. The library should also work on other Raspberry Pi variants, I just haven't gotten around to testing them yet.

The tests can be cross-compiled from other platforms using:

GOOS=linux GOARCH=arm GOARM=6 go test -c

Later Pis can also use ARM7 (GOARM=7).

Benchmarks

The tests include benchmarks on reads, writes, bulk reads and writes, and interrupt latency.

These are the results from a Raspberry Pi Zero W running Linux v5.10 and built with go1.15.6:

$ ./gpiod.test -platform=rpi -test.bench=.*
goos: linux
goarch: arm
pkg: github.com/warthog618/gpiod
BenchmarkChipNewClose              265       3949958 ns/op
BenchmarkLineInfo                28420         40192 ns/op
BenchmarkLineReconfigure         26079         46121 ns/op
BenchmarkLineValue              114961         10176 ns/op
BenchmarkLinesValues             66969         17367 ns/op
BenchmarkLineSetValue            92529         12531 ns/op
BenchmarkLinesSetValues          65965         17309 ns/op
BenchmarkInterruptLatency         1827        638202 ns/op
PASS

Prerequisites

The library targets Linux with support for the GPIO character device API. That generally means that /dev/gpiochip0 exists.

The caller must have access to the character device - typically /dev/gpiochip0. That is generally root unless you have changed the permissions of that device.

The Bias line options and the Line.Reconfigure method both require Linux v5.5 or later.

Debounce and other uAPI v2 features require Linux v5.10 or later.

The requirements for each configuration option are noted in that section.

Release Notes

v0.8.0

Add top level RequestLine and RequestLines functions to simplify common use cases.

blinker and watcher examples interwork with each other on a Raspberry Pi with a jumper across J8-15 and J8-16.

Fix deadlock in gpiodctl set no-wait.

v0.7.0

LineEvent exposes sequence numbers for uAPI v2 events.

Info tools (gpiodctl info and gpioinfo) report debounce-period.

gpiodctl mon and watcher example report event sequence numbers.

gpiodctl mon supports setting debounce period.

gpiodctl detect reports kernel uAPI version in use.

Watchers use Eventfd instead of pipes to reduce open file descriptors.

Start migrating to Go 1.17 go:build style build tags.

Make licensing REUSE compliant.

v0.6.0

gpiod now supports both the old GPIO uAPI (v1) and the newer (v2) introduced in Linux v5.10. The library automatically detects the available uAPI versions and makes use of the latest.

Applications written for uAPI v1 will continue to work with uAPI v2.

Applications that make use of v2 specific features will return errors when run on Linux kernels prior to v5.10.

Breaking API changes:

  1. The event handler parameter has been moved from edge options into the WithEventHandler(eh) option to allow for reconfiguration of edge detection which is supported in Linux v5.10.

    Old edge options should be replaced with the WithEventHandler option and the now parameterless edge option, e.g.:

    s/gpiod\.WithBothEdges(/gpiod.WithBothEdges, gpiod.WithEventHandler(/g
    
  2. WithBiasDisable is renamed WithBiasDisabled. This option is probably rarely used and the renaming is trivial, so no backward compatibility is provided.

  3. FindLine has been dropped as line names are not guaranteed to be unique. Iterating over the available chips and lines to search for line by name can be easily done - the Chips function provides the list of available chips as a starting point.

    Refer to the find command in gpiodctl for example code.

Documentation

Overview

Package gpiod is a library for accessing GPIO pins/lines on Linux platforms using the GPIO character device.

This is a Go equivalent of libgpiod.

Supports:

  • Line direction (input/output)
  • Line write (active/inactive)
  • Line read (active/inactive)
  • Line bias (pull-up/pull-down/disabled)
  • Line drive (push-pull/open-drain/open-source)
  • Line level (active-high/active-low)
  • Line edge detection (rising/falling/both)
  • Line labels
  • Collections of lines for near simultaneous reads and writes on multiple lines

Example of use:

v := 0
l, err := gpiod.RequestLine("gpiochip0", 4, gpiod.AsOutput(v))
if err != nil {
	panic(err)
}
for {
	<-time.After(time.Second)
	v ^= 1
	l.SetValue(v)
}

Index

Constants

View Source
const AsActiveHigh = LevelOption(false)

AsActiveHigh indicates that a line be considered active when the line level is high.

This is the default active level.

View Source
const AsActiveLow = LevelOption(true)

AsActiveLow indicates that a line be considered active when the line level is low.

View Source
const AsInput = InputOption(0)

AsInput indicates that a line be requested as an input.

This option overrides and clears any previous Output, OpenDrain, or OpenSource options.

View Source
const AsIs = AsIsOption(0)

AsIs indicates that a line be requested as neither an input or output.

That is its direction is left as is. This option overrides and clears any previous Input or Output options.

View Source
const AsOpenDrain = LineDriveOpenDrain

AsOpenDrain indicates that a line be driven low but left floating for high.

This option sets the Output option and overrides and clears any previous Input, RisingEdge, FallingEdge, BothEdges, OpenSource, or Debounce options.

View Source
const AsOpenSource = LineDriveOpenSource

AsOpenSource indicates that a line be driven high but left floating for low.

This option sets the Output option and overrides and clears any previous Input, RisingEdge, FallingEdge, BothEdges, OpenDrain, or Debounce options.

View Source
const AsPushPull = LineDrivePushPull

AsPushPull indicates that a line be driven both low and high.

This option sets the Output option and overrides and clears any previous Input, RisingEdge, FallingEdge, BothEdges, OpenDrain, OpenSource or Debounce options.

View Source
const Defaulted = DefaultedOption(0)

Defaulted resets all configuration options to default values.

This option provides the means to simply reset all configuration options to their default values. This is rarely necessary but is made available for completeness.

When applied within WithLines() it resets the configuration of the lines to the default for the request, effectively clearing all previous WithLines() options for the specified offsets. If no offsets are specified then the configurarion for all offsets is reset to the request default.

When applied outside WithLines() it resets the default configuration for the request itself to default values but leaves any configuration set within WithLines() unchanged.

View Source
const WithBiasAsIs = LineBiasUnknown

WithBiasAsIs indicates that a line have its internal bias left unchanged.

This option corresponds to the default bias configuration and its only useful application is to clear any previous bias option in a chain of LineOptions, before that configuration is applied.

Requires Linux v5.5 or later.

View Source
const WithBiasDisabled = LineBiasDisabled

WithBiasDisabled indicates that a line have its internal bias disabled.

This option overrides and clears any previous bias options.

Requires Linux v5.5 or later.

View Source
const WithBothEdges = LineEdgeBoth

WithBothEdges indicates that a line will generate events when its active state transitions from low to high and from high to low.

Events are forwarded to the provided handler function.

This option sets the Input option and overrides and clears any previous Output, OpenDrain, or OpenSource options.

View Source
const WithFallingEdge = LineEdgeFalling

WithFallingEdge indicates that a line will generate events when its active state transitions from high to low.

Events are forwarded to the provided handler function.

This option sets the Input option and overrides and clears any previous Output, OpenDrain, or OpenSource options.

View Source
const WithMonotonicEventClock = LineEventClockMonotonic

WithMonotonicEventClock specifies that the edge event timestamps are sourced from CLOCK_MONOTONIC.

This option corresponds to the default event clock configuration and its only useful application is to clear any previous event clock option in a chain of LineOptions, before that configuration is applied.

View Source
const WithPullDown = LineBiasPullDown

WithPullDown indicates that a line have its internal pull-down enabled.

This option overrides and clears any previous bias options.

Requires Linux v5.5 or later.

View Source
const WithPullUp = LineBiasPullUp

WithPullUp indicates that a line have its internal pull-up enabled.

This option overrides and clears any previous bias options.

Requires Linux v5.5 or later.

View Source
const WithRealtimeEventClock = LineEventClockRealtime

WithRealtimeEventClock specifies that the edge event timestamps are sourced from CLOCK_REALTIME.

Requires Linux v5.11 or later.

View Source
const WithRisingEdge = LineEdgeRising

WithRisingEdge indicates that a line will generate events when its active state transitions from low to high.

Events are forwarded to the provided handler function.

This option sets the Input option and overrides and clears any previous Output, OpenDrain, or OpenSource options.

View Source
const WithoutEdges = LineEdgeNone

WithoutEdges indicates that a line will not generate events due to active state transitions.

This is the default for line requests, but allows the removal of edge detection by reconfigure.

This option sets the Input option and overrides and clears any previous Output, OpenDrain, or OpenSource options.

The WithoutEdges option requires Linux v5.10 or later.

Variables

View Source
var (
	// ErrClosed indicates the chip or line has already been closed.
	ErrClosed = errors.New("already closed")

	// ErrConfigOverflow indicates the provided configuration is too complicated
	// to be mapped to the kernel uAPI.
	//
	// Reduce the number of line options or split the request into multiple
	// requests for smaller sets of lines.
	ErrConfigOverflow = errors.New("configuration too complex to map to kernel uAPI")

	// ErrInvalidOffset indicates a line offset is invalid.
	ErrInvalidOffset = errors.New("invalid offset")

	// ErrNotCharacterDevice indicates the device is not a character device.
	ErrNotCharacterDevice = errors.New("not a character device")

	// ErrPermissionDenied indicates caller does not have required permissions
	// for the operation.
	ErrPermissionDenied = errors.New("permission denied")
)

Functions

func Chips

func Chips() []string

Chips returns the names of the available GPIO devices.

func IsChip

func IsChip(name string) error

IsChip checks if the named device is an accessible GPIO character device.

Returns an error if not.

Types

type ABIVersionOption

type ABIVersionOption int

ABIVersionOption selects the version of the GPIO ioctl commands to use.

The default is to use the latest version supported by the kernel.

func WithABIVersion

func WithABIVersion(version int) ABIVersionOption

WithABIVersion indicates the version of the GPIO ioctls to use.

The default is to use the latest version supported by the kernel.

ABI version 2 requires Linux v5.10 or later.

type AsIsOption

type AsIsOption int

AsIsOption indicates the line direction should be left as is.

type Chip

type Chip struct {

	// The system name for this chip.
	Name string

	// A more individual label for the chip.
	Label string
	// contains filtered or unexported fields
}

Chip represents a single GPIO chip that controls a set of lines.

func NewChip

func NewChip(name string, options ...ChipOption) (*Chip, error)

NewChip opens a GPIO character device.

func (*Chip) Close

func (c *Chip) Close() error

Close releases the Chip.

It does not release any lines which may be requested - they must be closed independently.

func (*Chip) LineInfo

func (c *Chip) LineInfo(offset int) (info LineInfo, err error)

LineInfo returns the publicly available information on the line.

This is always available and does not require requesting the line.

func (*Chip) Lines

func (c *Chip) Lines() int

Lines returns the number of lines that exist on the GPIO chip.

func (*Chip) RequestLine

func (c *Chip) RequestLine(offset int, options ...LineReqOption) (*Line, error)

RequestLine requests control of a single line on the chip.

If granted, control is maintained until the Line is closed.

func (*Chip) RequestLines

func (c *Chip) RequestLines(offsets []int, options ...LineReqOption) (*Lines, error)

RequestLines requests control of a collection of lines on the chip.

If granted, control is maintained until the Lines are closed.

func (*Chip) UapiAbiVersion

func (c *Chip) UapiAbiVersion() int

UapiAbiVersion returns the version of the GPIO uAPI the chip is using.

func (*Chip) UnwatchLineInfo

func (c *Chip) UnwatchLineInfo(offset int) error

UnwatchLineInfo disables watching changes to line info.

Requires Linux v5.7 or later.

func (*Chip) WatchLineInfo

func (c *Chip) WatchLineInfo(offset int, lich InfoChangeHandler) (info LineInfo, err error)

WatchLineInfo enables watching changes to line info for the specified lines.

The changes are reported via the chip InfoChangeHandler. Repeated calls replace the InfoChangeHandler.

Requires Linux v5.7 or later.

type ChipOption

type ChipOption interface {
	// contains filtered or unexported methods
}

ChipOption defines the interface required to provide a Chip option.

type ChipOptions

type ChipOptions struct {
	// contains filtered or unexported fields
}

ChipOptions contains the options for a Chip.

type ConsumerOption

type ConsumerOption string

ConsumerOption defines the consumer label for a line.

func WithConsumer

func WithConsumer(consumer string) ConsumerOption

WithConsumer provides the consumer label for the line.

When applied to a chip it provides the default consumer label for all lines requested by the chip.

type DebounceOption

type DebounceOption time.Duration

DebounceOption indicates that a line will be debounced.

The DebounceOption requires Linux v5.10 or later.

func WithDebounce

func WithDebounce(period time.Duration) DebounceOption

WithDebounce indicates that a line will be debounced with the specified debounce period.

This option sets the Input option and overrides and clears any previous Output, OpenDrain, or OpenSource options.

Requires Linux v5.10 or later.

type DefaultedOption

type DefaultedOption int

DefaultedOption resets the configuration to default values.

type ErrUapiIncompatibility

type ErrUapiIncompatibility struct {
	Feature    string
	AbiVersion int
}

ErrUapiIncompatibility indicates the feature is not supported by the given kernel uAPI version.

func (ErrUapiIncompatibility) Error

func (e ErrUapiIncompatibility) Error() string

type EventBufferSizeOption

type EventBufferSizeOption int

EventBufferSizeOption provides a suggested minimum number of events the kernel will buffer for the line request.

The EventBufferSizeOption requires Linux v5.10 or later.

func WithEventBufferSize

func WithEventBufferSize(size int) EventBufferSizeOption

WithEventBufferSize suggests a minimum number of events the kernel will buffer for the line request.

Note that the value is only a suggestion, and the kernel may set higher values or place a cap on the buffer size.

A zero value (the default) indicates that the kernel should use its default buffer size (the number of requested lines * 16).

Requires Linux v5.10 or later.

type EventHandler

type EventHandler func(LineEvent)

EventHandler is a receiver for line events.

func WithEventHandler

func WithEventHandler(e EventHandler) EventHandler

WithEventHandler indicates that a line will generate events when its active state transitions from high to low.

Events are forwarded to the provided handler function.

To maintain event ordering, the event handler is called serially for each event from the requested lines. To minimize the possiblity of overflowing the queue of events in the kernel, the event handler should handle or hand-off the event and return as soon as possible.

Note that calling Close on the requested line from within the event handler will result in deadlock, as the Close waits for the event handler to return. Therefore the Close must be called from a different goroutine.

type InfoChangeHandler

type InfoChangeHandler func(LineInfoChangeEvent)

InfoChangeHandler is a receiver for line info change events.

type InputOption

type InputOption int

InputOption indicates the line direction should be set to an input.

type LevelOption

type LevelOption bool

LevelOption determines the line level that is considered active.

type Line

type Line struct {
	// contains filtered or unexported fields
}

Line represents a single requested line.

func RequestLine

func RequestLine(chip string, offset int, options ...LineReqOption) (*Line, error)

RequestLine requests control of a single line on a chip.

If granted, control is maintained until the Line is closed.

func (*Line) Chip

func (l *Line) Chip() string

Chip returns the name of the chip from which the line was requested.

func (*Line) Close

func (l *Line) Close() error

Close releases all resources held by the requested line.

Note that this includes waiting for any running event handler to return. As a consequence the Close must not be called from the context of the event handler - the Close should be called from a different goroutine.

func (*Line) Info

func (l *Line) Info() (info LineInfo, err error)

Info returns the information about the line.

func (*Line) Offset

func (l *Line) Offset() int

Offset returns the offset of the line within the chip.

func (*Line) Reconfigure

func (l *Line) Reconfigure(options ...LineConfigOption) error

Reconfigure updates the configuration of the requested line(s).

Configuration for options other than those passed in remain unchanged.

Not valid for lines with edge detection enabled.

Requires Linux v5.5 or later.

func (*Line) SetValue

func (l *Line) SetValue(value int) error

SetValue sets the current active state of the line.

Only valid for output lines.

func (*Line) UapiAbiVersion

func (l *Line) UapiAbiVersion() int

UapiAbiVersion returns the version of the GPIO uAPI the line is using.

func (*Line) Value

func (l *Line) Value() (int, error)

Value returns the current value (active state) of the line.

type LineBias

type LineBias int

LineBias indicates the bias applied to a line.

const (
	// LineBiasUnknown indicates the line bias is unknown.
	LineBiasUnknown LineBias = iota

	// LineBiasDisabled indicates the line bias is disabled.
	LineBiasDisabled

	// LineBiasPullUp indicates the line has pull up enabled.
	LineBiasPullUp

	// LineBiasPullDown indicates the line has pull down enabled.
	LineBiasPullDown
)

type LineConfig

type LineConfig struct {
	// A flag indicating if the line is active low.
	ActiveLow bool

	// The line direction.
	Direction LineDirection

	// The line drive.
	Drive LineDrive

	// The line bias.
	Bias LineBias

	// The line edge detection.
	EdgeDetection LineEdge

	// A flag indicating if the line is debounced.
	Debounced bool

	// The line debounce period.
	DebouncePeriod time.Duration

	// The source clock for events on the line.
	EventClock LineEventClock
}

LineConfig contains the configuration parameters for the line.

type LineConfigOption

type LineConfigOption interface {
	// contains filtered or unexported methods
}

LineConfigOption defines the interface required to update an option for Line and Lines.

type LineDirection

type LineDirection int

LineDirection indicates the direction of a line.

const (
	// LineDirectionUnknown indicate the line direction is unknown.
	LineDirectionUnknown LineDirection = iota

	// LineDirectionInput indicates the line is an input.
	LineDirectionInput

	// LineDirectionOutput indicates the line is an output.
	LineDirectionOutput
)

type LineDrive

type LineDrive int

LineDrive indicates the drive of an output line.

const (
	// LineDrivePushPull indicates the line is driven in both directions.
	LineDrivePushPull LineDrive = iota

	// LineDriveOpenDrain indicates the line is an open drain output.
	LineDriveOpenDrain

	// LineDriveOpenSource indicates the line is an open souce output.
	LineDriveOpenSource
)

type LineEdge

type LineEdge int

LineEdge indicates the edges detected by the line.

const (
	// LineEdgeNone indicates the line edge detection is disabled.
	LineEdgeNone LineEdge = iota

	// LineEdgeRising indicates the line has rising edge detection enabled.
	LineEdgeRising

	// LineEdgeFalling indicates the line has falling edge detection enabled.
	LineEdgeFalling

	// LineEdgeBoth indicates the line has both rising and falling edge
	// detection enabled.
	LineEdgeBoth = LineEdgeRising | LineEdgeFalling
)

type LineEvent

type LineEvent struct {
	// The line offset within the GPIO chip.
	Offset int

	// Timestamp indicates the time the event was detected.
	//
	// The timestamp is intended for accurately measuring intervals between
	// events. It is not guaranteed to be based on a particular clock. It has
	// been based on CLOCK_REALTIME, but from Linux v5.7 it is based on
	// CLOCK_MONOTONIC.
	Timestamp time.Duration

	// The type of state change event this structure represents.
	Type LineEventType

	// The seqno for this event in all events on all lines in this line request.
	//
	// Requires uAPI v2.
	Seqno uint32

	// The seqno for this event in all events in this line.
	//
	// Requires uAPI v2.
	LineSeqno uint32
}

LineEvent represents a change in the state of a line.

type LineEventClock

type LineEventClock int

LineEventClock indicates the source clock used to timestamp edge events.

const (
	// LineEventClockMonotonic indicates the source clock is CLOCK_MONOTONIC.
	LineEventClockMonotonic LineEventClock = iota

	// LineEventClockRealtime indicates the source clock is CLOCK_REALTIME.
	LineEventClockRealtime
)

type LineEventType

type LineEventType int

LineEventType indicates the type of change to the line active state.

Note that for active low lines a low line level results in a high active state.

const (

	// LineEventRisingEdge indicates an inactive to active event.
	LineEventRisingEdge LineEventType

	// LineEventFallingEdge indicates an active to inactive event.
	LineEventFallingEdge
)

type LineInfo

type LineInfo struct {
	// The line offset within the chip.
	Offset int

	// The system name for the line.
	Name string

	// A string identifying the requester of the line, if requested.
	Consumer string

	// The line is in use.
	Used bool

	// The configuration parameters for the line.
	Config LineConfig
}

LineInfo contains a summary of publicly available information about the line.

type LineInfoChangeEvent

type LineInfoChangeEvent struct {
	// Info is the updated line info.
	Info LineInfo

	// Timestamp indicates the time the event was detected.
	//
	// The timestamp is intended for accurately measuring intervals between
	// events. It is not guaranteed to be based on a particular clock, but from
	// Linux v5.7 it is based on CLOCK_MONOTONIC.
	Timestamp time.Duration

	// The type of info change event this structure represents.
	Type LineInfoChangeType
}

LineInfoChangeEvent represents a change in the info a line.

type LineInfoChangeType

type LineInfoChangeType int

LineInfoChangeType indicates the type of change to the line info.

const (

	// LineRequested indicates the line has been requested.
	LineRequested LineInfoChangeType

	// LineReleased indicates the line has been released.
	LineReleased

	// LineReconfigured indicates the line configuration has changed.
	LineReconfigured
)

type LineReqOption

type LineReqOption interface {
	// contains filtered or unexported methods
}

LineReqOption defines the interface required to provide an option for Line and Lines as part of a line request.

type Lines

type Lines struct {
	// contains filtered or unexported fields
}

Lines represents a collection of requested lines.

func RequestLines

func RequestLines(chip string, offsets []int, options ...LineReqOption) (*Lines, error)

RequestLines requests control of a collection of lines on a chip.

If granted, control is maintained until the Lines are closed.

func (*Lines) Chip

func (l *Lines) Chip() string

Chip returns the name of the chip from which the line was requested.

func (*Lines) Close

func (l *Lines) Close() error

Close releases all resources held by the requested line.

Note that this includes waiting for any running event handler to return. As a consequence the Close must not be called from the context of the event handler - the Close should be called from a different goroutine.

func (*Lines) Info

func (l *Lines) Info() ([]*LineInfo, error)

Info returns the information about the lines.

func (*Lines) Offsets

func (l *Lines) Offsets() []int

Offsets returns the offsets of the lines within the chip.

func (*Lines) Reconfigure

func (l *Lines) Reconfigure(options ...LineConfigOption) error

Reconfigure updates the configuration of the requested line(s).

Configuration for options other than those passed in remain unchanged.

Not valid for lines with edge detection enabled.

Requires Linux v5.5 or later.

func (*Lines) SetValues

func (l *Lines) SetValues(values []int) error

SetValues sets the current active state of the collection of lines.

Only valid for output lines.

All lines in the set are set at once. If insufficient values are provided then the remaining lines are set to inactive. If too many values are provided then the surplus values are ignored.

func (*Lines) UapiAbiVersion

func (l *Lines) UapiAbiVersion() int

UapiAbiVersion returns the version of the GPIO uAPI the line is using.

func (*Lines) Values

func (l *Lines) Values(values []int) error

Values returns the current values (active state) of the collection of lines.

Gets as many values from the set, in order, as can be fit in values, up to the full set.

type LinesOption

type LinesOption struct {
	// contains filtered or unexported fields
}

LinesOption specifies line options that are to be applied to a subset of the lines in a request.

func WithLines

func WithLines(offsets []int, options ...SubsetLineConfigOption) LinesOption

WithLines specifies line options to be applied to a subset of the lines in a request.

The offsets should be a strict subset of the offsets provided to RequestLines(). Any offsets outside that set are ignored.

type OutputOption

type OutputOption []int

OutputOption indicates the line direction should be set to an output.

func AsOutput

func AsOutput(values ...int) OutputOption

AsOutput indicates that a line or lines be requested as an output.

The initial active state for the line(s) can optionally be provided. If fewer values are provided than lines then the remaining lines default to inactive.

This option overrides and clears any previous Input, RisingEdge, FallingEdge, BothEdges, or Debounce options.

type SubsetLineConfigOption

type SubsetLineConfigOption interface {
	// contains filtered or unexported methods
}

SubsetLineConfigOption defines the interface required to update an option for a subset of requested lines.

Directories

Path Synopsis
Package uapi provides the Linux GPIO UAPI definitions for gpiod.
Package uapi provides the Linux GPIO UAPI definitions for gpiod.

Jump to

Keyboard shortcuts

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