625 lines
20 KiB
Markdown
625 lines
20 KiB
Markdown
<!--
|
|
SPDX-FileCopyrightText: 2019 Kent Gibson <warthog618@gmail.com>
|
|
|
|
SPDX-License-Identifier: MIT
|
|
-->
|
|
|
|
# gpiocdev
|
|
|
|
[![Build Status](https://img.shields.io/github/actions/workflow/status/warthog618/go-gpiocdev/go.yml?logo=github&branch=master)](https://github.com/warthog618/go-gpiocdev/actions/workflows/go.yml)
|
|
[![PkgGoDev](https://pkg.go.dev/badge/github.com/warthog618/go-gpiocdev)](https://pkg.go.dev/github.com/warthog618/go-gpiocdev)
|
|
[![Go Report Card](https://goreportcard.com/badge/github.com/warthog618/go-gpiocdev)](https://goreportcard.com/report/github.com/warthog618/go-gpiocdev)
|
|
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/warthog618/go-gpiocdev/blob/master/LICENSE)
|
|
|
|
A native Go library for Linux GPIO.
|
|
|
|
**gpiocdev** 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](https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/)**
|
|
library. The intent is not to mirror the **libgpiod** API but to provide the
|
|
equivalent functionality.
|
|
|
|
## Features
|
|
|
|
Supports the following functionality per line and for collections of lines:
|
|
|
|
- direction (input/output)<sup>**1**</sup>
|
|
- write (active/inactive)
|
|
- read (active/inactive)
|
|
- active high/low (defaults to high)
|
|
- output mode (push-pull/open-drain/open-source)
|
|
- pull up/down<sup>**2**</sup>
|
|
- watches and edge detection (rising/falling/both)
|
|
- chip and line labels
|
|
- debouncing input lines<sup>**3**</sup>
|
|
- different configurations for lines within a collection<sup>**3**</sup>
|
|
|
|
<sup>**1**</sup> Dynamically changing line direction without releasing the line
|
|
requires Linux 5.5 or later.
|
|
|
|
<sup>**2**</sup> Requires Linux 5.5 or later.
|
|
|
|
<sup>**3**</sup> Requires Linux 5.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):
|
|
|
|
```go
|
|
import "github.com/warthog618/gpiocdev"
|
|
|
|
...
|
|
|
|
in, _ := gpiocdev.RequestLine("gpiochip0", 2, gpiocdev.AsInput)
|
|
val, _ := in.Value()
|
|
out, _ := gpiocdev.RequestLine("gpiochip0", 3, gpiocdev.AsOutput(val))
|
|
|
|
...
|
|
```
|
|
|
|
Error handling and releasing of resources omitted for brevity.
|
|
|
|
## Usage
|
|
|
|
```go
|
|
import "github.com/warthog618/gpiocdev"
|
|
```
|
|
|
|
Error handling is omitted from the following examples for brevity.
|
|
|
|
### Line Requests
|
|
|
|
To read or alter the value of a
|
|
[line](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#Line) it must first be
|
|
requested using [*gpiocdev.RequestLine*](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#RequestLine):
|
|
|
|
```go
|
|
l, _ := gpiocdev.RequestLine("gpiochip0", 4) // in its existing state
|
|
```
|
|
|
|
or from the [*Chip*](#chip-initialization) object using
|
|
[*Chip.RequestLine*](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#Chip.RequestLine):
|
|
|
|
```go
|
|
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:
|
|
|
|
```go
|
|
l, _ := c.RequestLine(rpi.J8p7) // using Raspberry Pi J8 mapping
|
|
```
|
|
|
|
The initial configuration of the line can be set by providing line
|
|
[configuration options](#configuration-options), as shown in this *AsOutput*
|
|
example:
|
|
|
|
```go
|
|
l, _ := gpiocdev.RequestLine("gpiochip0", 4, gpiocdev.AsOutput(1)) // as an output line
|
|
```
|
|
|
|
Multiple lines from the same chip may be requested as a collection of
|
|
[lines](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#Lines) using
|
|
[*gpiocdev.RequestLines*](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#RequestLines)
|
|
|
|
```go
|
|
ll, _ := gpiocdev.RequestLines("gpiochip0", []int{0, 1, 2, 3}, gpiocdev.AsOutput(0, 0, 1, 1))
|
|
```
|
|
|
|
or from a Chip object using
|
|
[*Chip.RequestLines*](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#Chip.RequestLines):
|
|
|
|
```go
|
|
ll, _ := c.RequestLines([]int{0, 1, 2, 3}, gpiocdev.AsOutput(0, 0, 1, 1))
|
|
```
|
|
|
|
When no longer required, the line(s) should be closed to release resources:
|
|
|
|
```go
|
|
l.Close()
|
|
ll.Close()
|
|
```
|
|
|
|
### Line Values
|
|
|
|
Lines must be requsted using [*RequestLine*](#line-requests) before their
|
|
values can be accessed.
|
|
|
|
#### Read Input
|
|
|
|
The current line value can be read with the
|
|
[*Value*](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#Line.Value)
|
|
method:
|
|
|
|
```go
|
|
r, _ := l.Value() // Read state from line (active / inactive)
|
|
```
|
|
|
|
For collections of lines, the level of all lines is read simultaneously using
|
|
the [*Values*](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#Lines.SetValues)
|
|
method:
|
|
|
|
```go
|
|
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*](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#Line.SetValue)
|
|
method:
|
|
|
|
```go
|
|
l.SetValue(1) // Set line active
|
|
l.SetValue(0) // Set line inactive
|
|
```
|
|
|
|
Also refer to the [blinker](example/blinker/blinker.go) example.
|
|
|
|
For collections of lines, all lines are set simultaneously using the
|
|
[*SetValues*](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#Lines.SetValues)
|
|
method:
|
|
|
|
```go
|
|
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*](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#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:
|
|
|
|
```go
|
|
func handler(evt gpiocdev.LineEvent) {
|
|
// handle edge event
|
|
}
|
|
|
|
l, _ = c.RequestLine(rpi.J8p7, gpiocdev.WithEventHandler(handler), gpiocdev.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:
|
|
|
|
```go
|
|
l.Close()
|
|
```
|
|
|
|
or by reconfiguring the requested lines to disable edge detection:
|
|
|
|
```go
|
|
l.Reconfigure(gpiocdev.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/watcher/watcher.go) example.
|
|
|
|
### Line Configuration
|
|
|
|
Line configuration is set via [options](#configuration-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:
|
|
|
|
```go
|
|
l.Reconfigure(gpiocdev.AsInput) // set direction to Input
|
|
ll.Reconfigure(gpiocdev.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 5.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:
|
|
|
|
```go
|
|
ll, _ = c.RequestLines([]int{0, 1, 2, 3}, gpiocdev.AsOutput(0, 0, 1, 1),
|
|
gpiocdev.WithLines([]int{0, 3}, gpiocdev.AsActiveLow),
|
|
gpiocdev.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:
|
|
|
|
```go
|
|
ll.Reconfigure(gpiocdev.WithLines([]int{0}, gpiocdev.AsActiveHigh))
|
|
```
|
|
|
|
or reset to the request configuration using the *Defaulted* option:
|
|
|
|
```go
|
|
ll.Reconfigure(gpiocdev.WithLines([]int{3}, gpiocdev.Defaulted))
|
|
```
|
|
|
|
Complex configurations require Linux 5.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*](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#NewChip) function.
|
|
|
|
```go
|
|
c, _ := gpiocdev.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:
|
|
|
|
```go
|
|
cc := gpiocdev.Chips()
|
|
```
|
|
|
|
Default attributes for Lines requested from the Chip can be set via
|
|
[configuration options](#configuration-options) to
|
|
[*NewChip*](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#NewChip).
|
|
|
|
```go
|
|
c, _ := gpiocdev.NewChip("gpiochip0", gpiocdev.WithConsumer("myapp"))
|
|
```
|
|
|
|
In this example the consumer label is defaulted to "myapp".
|
|
|
|
When no longer required, the chip should be closed to release resources:
|
|
|
|
```go
|
|
c.Close()
|
|
```
|
|
|
|
Closing a chip does not close or otherwise alter the state of any lines
|
|
requested from the chip.
|
|
|
|
### Line Info
|
|
|
|
[Info](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#LineInfo) about a line can
|
|
be read at any time from the chip using the
|
|
[*LineInfo*](https://pkg.go.dev/github.com/warthog618/go-gpiocdev#Chip.LineInfo)
|
|
method:
|
|
|
|
```go
|
|
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:
|
|
|
|
```go
|
|
inf, _ := l.Info()
|
|
infs, _ := ll.Info()
|
|
```
|
|
|
|
#### Info Watches
|
|
|
|
Changes to the line info can be monitored by adding an info watch for the line:
|
|
|
|
```go
|
|
func infoChangeHandler( evt gpiocdev.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](#edge-watches) for monitoring
|
|
line value.
|
|
|
|
An info watch can be cancelled by unwatching:
|
|
|
|
```go
|
|
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:
|
|
|
|
```go
|
|
l, _ := c.RequestLine(4, gpiocdev.AsActiveLow) // during request
|
|
l.Reconfigure(gpiocdev.AsActiveHigh) // once requested
|
|
```
|
|
|
|
Lines are typically active high by default.
|
|
|
|
##### Direction
|
|
|
|
The line direction can be controlled using the *AsInput* and *AsOutput* options:
|
|
|
|
```go
|
|
l, _ := c.RequestLine(4, gpiocdev.AsInput) // during request
|
|
l.Reconfigure(gpiocdev.AsInput) // set direction to Input
|
|
l.Reconfigure(gpiocdev.AsOutput(0)) // set direction to Output (and value to inactive)
|
|
```
|
|
|
|
##### Bias
|
|
|
|
The bias options control the pull up/down state of the line:
|
|
|
|
```go
|
|
l, _ = c.RequestLine(4, gpiocdev.WithPullUp) // during request
|
|
l.Reconfigure(gpiocdev.WithBiasDisabled) // once requested
|
|
```
|
|
|
|
The bias options require Linux 5.5 or later.
|
|
|
|
##### Drive
|
|
|
|
The drive options control how an output line is driven when active and inactive:
|
|
|
|
```go
|
|
l,_ := c.RequestLine(4, gpiocdev.AsOpenDrain) // during request
|
|
l.Reconfigure(gpiocdev.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.
|
|
|
|
```go
|
|
period := 10 * time.Millisecond
|
|
l, _ = c.RequestLine(4, gpiocdev.WithDebounce(period))// during request
|
|
l.Reconfigure(gpiocdev.WithDebounce(period)) // once requested
|
|
```
|
|
|
|
The WithDebounce option requires Linux 5.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](#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 5.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-5.7 | CLOCK_REALTIME
|
|
5.7 - 5.10 | CLOCK_MONOTONIC
|
|
5.11 and later | configurable (defaults to CLOCK_MONOTONIC)
|
|
|
|
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
|
|
---|---|---
|
|
*WithConsumer*<sup>**1**</sup> | 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
|
|
*AsIs*<sup>**2**</sup> | Direction | Request lines in their current input/output state (**default**)
|
|
*AsOutput(\<values\>...)*<sup>**3**</sup> | 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)<sup>**1**</sup>* | | Send edge events detected on requested lines to the provided handler
|
|
*WithEventBufferSize(num)<sup>**1**,**5**</sup>* | | Suggest the minimum number of events that can be stored in the kernel event buffer for the requested lines
|
|
*WithFallingEdge* | Edge Detection<sup>**3**</sup> | Request lines with falling edge detection
|
|
*WithRisingEdge* | Edge Detection<sup>**3**</sup> | Request lines with rising edge detection
|
|
*WithBothEdges* | Edge Detection<sup>**3**</sup> | Request lines with rising and falling edge detection
|
|
*WithoutEdges*<sup>**5**</sup> | Edge Detection<sup>**3**</sup> | Request lines with edge detection disabled (**default**)
|
|
*WithBiasAsIs* | Bias<sup>**4**</sup> | Request the lines have their bias setting left unaltered (**default**)
|
|
*WithBiasDisabled* | Bias<sup>**4**</sup> | Request the lines have internal bias disabled
|
|
*WithPullDown* | Bias<sup>**4**</sup> | Request the lines have internal pull-down enabled
|
|
*WithPullUp* | Bias<sup>**4**</sup> | Request the lines have internal pull-up enabled
|
|
*WithDebounce(period)*<sup>**5**</sup> | Debounce | Request the lines be debounced with the provided period
|
|
*WithMonotonicEventClock* | Event Clock | Request the timestamp in edge events use the monotonic clock (**default**)
|
|
*WithRealtimeEventClock*<sup>**6**</sup> | Event Clock | Request the timestamp in edge events use the realtime clock
|
|
*WithLines(offsets, options...)*<sup>**3**,**5**</sup> | | Specify configuration options for a subset of lines in a request
|
|
*Defaulted*<sup>**5**</sup> | | 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.
|
|
|
|
<sup>**1**</sup> Can be applied to either *NewChip* or *Chip.RequestLine*, but
|
|
cannot be used with *Line.Reconfigure*.
|
|
|
|
<sup>**2**</sup> Can be applied to *Chip.RequestLine*, but cannot be used
|
|
with *NewChip* or *Line.Reconfigure*.
|
|
|
|
<sup>**3**</sup> Can be applied to either *Chip.RequestLine* or
|
|
*Line.Reconfigure*, but cannot be used with *NewChip*.
|
|
|
|
<sup>**4**</sup> Requires Linux 5.5 or later.
|
|
|
|
<sup>**5**</sup> Requires Linux 5.10 or later.
|
|
|
|
<sup>**6**</sup> Requires Linux 5.11 or later.
|
|
|
|
## Installation
|
|
|
|
On Linux:
|
|
|
|
```shell
|
|
go get github.com/warthog618/go-gpiocdev
|
|
```
|
|
|
|
For other platforms, where you intend to cross-compile for Linux, don't attempt
|
|
to compile the package when it is installed:
|
|
|
|
```shell
|
|
go get -d github.com/warthog618/go-gpiocdev
|
|
```
|
|
|
|
## Tools
|
|
|
|
A companion package, **[gpiocdev-cli](github.com/warthog618/go-gpiocdev-cli)** provides a command line tool that allows
|
|
manual or scripted manipulation of GPIO lines. This utility combines the Go
|
|
equivalent of all the **libgpiod** command line tools into a single tool.
|
|
|
|
## 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.19 or later to run, built with
|
|
**CONFIG_GPIO_SIM** set or as a module.
|
|
|
|
The tests must be run as root, to allow contruction of **gpio-sims**.
|
|
They can still be built as an unprivileged user, e.g.
|
|
|
|
```shell
|
|
$ go test -c
|
|
```
|
|
|
|
but must be run as root.
|
|
|
|
The tests can also be cross-compiled for other platforms.
|
|
e.g. build tests for a Raspberry Pi using:
|
|
|
|
```shell
|
|
$ 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 6.4 and built
|
|
with go1.20.6:
|
|
|
|
```shell
|
|
$ ./go-gpiocdev.test -test.bench=.*
|
|
goos: linux
|
|
goarch: arm
|
|
pkg: github.com/warthog618/go-gpiocdev
|
|
BenchmarkChipNewClose 248 4381075 ns/op
|
|
BenchmarkLineInfo 24651 47278 ns/op
|
|
BenchmarkLineReconfigure 20312 55273 ns/op
|
|
BenchmarkLineValue 71774 14933 ns/op
|
|
BenchmarkLinesValues 54920 24659 ns/op
|
|
BenchmarkLineSetValue 73359 16501 ns/op
|
|
BenchmarkLinesSetValues 53557 21056 ns/op
|
|
BenchmarkInterruptLatency 105 10407929 ns/op
|
|
PASS
|
|
```
|
|
|
|
The latency benchmark is no longer representative as the measurement now depends
|
|
on how quickly **gpio-sim** can toggle lines, and that is considerably slower
|
|
than how quickly **gpiocdev** responds. For comparison, the same test using
|
|
looped Raspberry Pi lines produced a result of ~640μsec on the same platform.
|
|
|
|
And on a Raspberry Pi 4 running Linux 6.4 (32bit kernel) and built with go1.20.6:
|
|
|
|
```shell
|
|
$ ./go-gpiocdev.test -test.bench=.*
|
|
goos: linux
|
|
goarch: arm
|
|
pkg: github.com/warthog618/go-gpiocdev
|
|
BenchmarkChipNewClose-4 9727 118291 ns/op
|
|
BenchmarkLineInfo-4 185316 6104 ns/op
|
|
BenchmarkLineReconfigure-4 364795 3205 ns/op
|
|
BenchmarkLineValue-4 1072785 1061 ns/op
|
|
BenchmarkLinesValues-4 816200 1428 ns/op
|
|
BenchmarkLineSetValue-4 1015972 1150 ns/op
|
|
BenchmarkLinesSetValues-4 715154 1717 ns/op
|
|
BenchmarkInterruptLatency-4 18439 61145 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 5.5 or
|
|
later.
|
|
|
|
Debounce and other uAPI v2 features require Linux 5.10 or later.
|
|
|
|
The requirements for each [configuration option](#configuration-options) are
|
|
noted in that section.
|