While we use it for edge event timestamps exclusively at the moment,
the actual enum names shouldn't limit its application and simply just
refer to existing clock types known by the GPIO uAPI. The relevant
functions are still called set/get_event_clock() as it's in line with
their functionality.
treewide: use plural 'events' in read_edge_event() functions
The read_edge_event() family of functions should actually be called
read_edge_events() as they universally allow to read more than one
event. We're converting wait_edge_event() too for consistency.
treewide: apply formatting changes with clang-format
Use linux kernel's .clang-format file to automatically improve the coding
style of libgpiod's C code base. We don't import the file into the
repository as it's not perfect and certain converted fragments were
rolled back because they looked better before the conversion.
bindings: python: tests: use the version parser from setuptools
We currently require the third-party packaging module to be installed in
order to run tests. Let's instead use the version parser that's already
available in setuptools.
We need to drop the reference count of the GVariants we create when
packing hogs and line names. This fixes all memory leaks in tests that
are caused by this bug.
Kent Gibson [Mon, 21 Nov 2022 10:22:51 +0000 (18:22 +0800)]
tools: add gpionotify
Add a gpionotify tool, based on gpiomon, to report line info change
events read from chip file descriptors.
Inspired by the gpio-watch tool in the linux kernel, but with gpiomon
features such as custom formatted output, filtering events of
interest and exiting after a number of events, so more useful for
scripting.
Default output is minimalist, so just time, event type and line id.
Full event details are available using the custom formatted output.
Kent Gibson [Mon, 21 Nov 2022 10:22:48 +0000 (18:22 +0800)]
tools: line name focussed rework
Rework the tool suite to support identifying lines by name and to
support operating on the GPIO lines available to the user at once, rather
than on one particular GPIO chip.
All tools, other than gpiodetect, now provide the name to (chip,offset)
mapping that was previously only performed by gpiofind. As names are not
guaranteed to be unique, a --strict option is provided for all tools to
either abort the operation or report all lines with the matching name, as
appropriate.
By default the tools operate on the first line found with a matching name.
Selection of line by (chip,offset) is still supported with a --chip
option, though it restricts the scope of the operation to an individual
chip. When the --chip option is specified, the lines are assumed to be
identified by offset where they parse as an integer, else by name.
To cater for the unusual case where a line name parses as an integer,
but is different from the offset, the --by-name option forces the lines
to be identified by name.
The updated tools are intentionally NOT backwardly compatible with the
previous tools. Using old command lines with the updated tools will
almost certainly fail, though migrating old command lines is generally as
simple as adding a '-c' before the chip.
In addition the individual tools are modified as follows:
gpiodetect:
Add the option to select individual chips.
gpioinfo:
Change the focus from chips to lines, so the scope can be
an individual line, a subset of lines, all lines on a particular chip,
or all the lines available to the user. For line scope a single line
summary is output for each line. For chip scope the existing format
displaying a summary of the chip and each of its lines is retained.
Line attributes are consolidated into a list format, and are extended
to cover all attributes supported by uAPI v2.
gpioget:
The default output format is becomes line=value, as per the
input for gpioset, and the value is reported as active or inactive,
rather than 0 or 1.
The previous format is available using the --numeric option.
Add an optional hold period between requesting a line and reading the
value to allow the line to settle once the requested configuration has
been applied (e.g. bias).
gpiomon:
Consolidate the edge options into a single option.
Add a debounce period option.
Add options to report event times as UTC or localtime.
Add format specifiers for GPIO chip path, line name, stringified event
type, and event time as a datetime.
Rearrange default output format to place fields with more predicable
widths to the left, and to separate major field groups with tabs.
Lines are identified consistent with the command line.
gpioset:
Add a hold period option that specifies the minimum period the line
value must be held for. This applies to all set options.
Support line values specified as active/inactive, on/off and
true/false, as well as 1/0.
Add a toggle option that specifies a time sequence over which the
requested lines should be toggled. If the sequence is 0 terminated then
gpioset exits when the sequence completes, else it repeats the sequence.
This allows for anything from simple blinkers to bit bashing from the
command line. e.g. gpioset -t 500ms LED=on
Add an interactive option to provide a shell-like interface to allow
manual or scripted manipulation of requested lines. A basic command set
allows lines to be get, set, or toggled, and to insert sleeps between
operations.
Remove the --mode, --sec, and --usec options.
The combination of hold period and interactive mode provide functionality
equivalent to the old --mode options. By default gpioset now holds the
line indefinitely, rather than exiting immediately. The old exit
behaviour can be emulated with a "-t 0" option.
Signed-off-by: Kent Gibson <warthog618@gmail.com>
[Bartosz: coding style tweaks, dropped stray newlines and spaces] Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
This commit is the result of a squash of all the commits created during
the development of libgpiod v2. This is done to preserve bisectability
of the git tree. It contains significant re-writes of the core C library
as well as C++ and python bindings. The tools have been adjusted to work
with the new API but have not undergone significant changes yet.
This commit contains the bulk of the work on libgpiod v2 but the
development continues with more changes planned.
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
[Ben: fix format specifier for uint64_t] Signed-off-by: Ben Hutchings <ben.hutchings@mind.be>
[Viresh: Fix ioctl number for gpiod_line_request_reconfigure_lines()] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
[Kent: bug fixes, improvements, better pointer contracts, type strictness] Signed-off-by: Kent Gibson <warthog618@gmail.com>
gpiosim: initialize the bank's num_lines field to 1
If we create a simulated chip and never set the num_lines property, the
num_lines field remains set to 0 and the potential lineX and hog
directories within the bank's directory will not get removed so the
removal of the bank's and device's directories will fail too leaving
a dangling chip in place.
Initialize bank->num_lines to 1 to avoid this issue.
Fixes: a2f6e8cd3540 ("libgpiosim: new library for controlling the gpio-sim module") Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
If a bank gets released before the device is disabled, the sysfs file
descriptor of that bank is leaked. close() it when releasing the bank.
While at it: improve two other details - unlink the configfs directory
after closing the file descriptor associated with it and remove an
unnecessary check when closing the sysfs descriptor when disabling the
device.
gpiosim: add an enum representing line active state
In order to avoid confusion and stress the fact that "value" represents
the logical state of a GPIO line, add a two-value enum with the names
"ACTIVE" and "INACTIVE" to the libgpiosim API.
If a bank gets dropped when the device is still enabled and before the
parent device, we leak the device path and chip name strings. This makes
sure we always free them.
Joel Stanley [Wed, 2 Feb 2022 12:01:23 +0000 (22:31 +1030)]
gpioinfo: Clean up scandir allocations
==3017== 176 (80 direct, 96 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==3017== at 0x483F6C7: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3017== by 0x491CE92: ??? (in /lib/libc.so.6)
==3017== by 0x10AAAC: main (gpioinfo.c:215)
The entires must be freed, and then the array itself.
Signed-off-by: Joel Stanley <joel@jms.id.au> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
Joel Stanley [Wed, 2 Feb 2022 12:32:48 +0000 (23:02 +1030)]
core: Fix gpiod_line_bulk_reset type
bulk->lines is an array of pointers, so it doesn't matter which pointer
type we specify to sizeof(). As it's a struct gpiod_line *, it would
make sense to use that.
Signed-off-by: Joel Stanley <joel@jms.id.au> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
libgpiosim: new library for controlling the gpio-sim module
Add a C library for controlling the gpio-sim kernel module from various
libgpiod test suites. This aims at replacing the old gpio-mockup module
and its user-space library - libgpio-mockup - in the project's tree.
I noticed that tools ptests fail on minimal yocto systems and the
culprit of that is missing the timeout command. Check for it before
launching the bats suite.
The current proposed v2.0 API for libgpiod contains so many changes
since v1.x that the items in TODO have become obsolete. For instance:
we can no longer rethink the bulk line objects because they no longer
exist. Same for C++ weak references - in the new version the objects
will no longer be copyable. Remove the libgpiod v2 items entirely.
Ahmad Fatoum [Tue, 27 Apr 2021 15:42:24 +0000 (17:42 +0200)]
tools: gpioget: add new --dir-as-is option for GPO read-back
Both legacy sysfs and new character device API support querying line
state of a GPIO configured as output. But while sysfs /value can
be read for these output GPIOs, gpioget unconditionally muxes the
line as input. To ease migration to the new user API, add a new
--dir-as-is parameter that doesn't force the line to input.
This is especially useful for GPIO controllers that maintain their
last configured output state.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
Currently libgpiod requires that the GPIO chip character device be named
'gpiochip%u' in devfs. However it's a perfectly valid use-case to have
the device file renamed by udev (or equivalent) to anything else.
Modify gpiod_is_gpiochip_device() to check the major and minor device
numbers first and then ensure that the device in question is associated
with the GPIO subsystem. No longer check the name.
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
GPIOD_API is unneccesarily polluting the user-facing headers. There's no
advantage to having it in public files. Let's make them internal to the
library. Upcoming modifications will also make GPIOD_BIT() redundant so
we'll be able to remove all macros unrelated to the main functionality
from gpiod.h.
This removes any trace of line updating from the API (C, C++ and Python).
The line objects will soon disappear entirely so in order to make the
gradual transition to the new data model easier, remove
gpiod_line_update().
This removes another two functions from the C API as well as their
bindings that don't make much sense (since the user should know if
they have requested the line or not).
core: switch to reference counting for gpio chip objects
The preferred approach in low-level system libraries is to make all
exposed data structures opaque and use reference counting for their
memory management. This changes the chip objects to only close their
underlying character device and release all resources once the reference
count goes down to 0. We remove the gpiod_chip_close() function and
replace it with gpiod_chip_ref() and gpiod_chip_unref().
Other objects in the API will either be removed or are not opaque yet
and will be reworked later.
Together with the removal of line objects, we'll entirely drop the
line bulk concept. In order to avoid having to update tests that will
soon be unneeded when introducing further changes, let's remove line
bulk test cases already.
We're preparing to entirely remove the line objects from the API and
split their functionality between two new objects: line_info and
line_request. The lookup functions must be limited in the process.
This reworks all the find_line methods to: a) always assume that names
looked for are unique within a single chip (because while it's
technically possible for GPIO line names to be non-unique, it doesn't
make sense to look for two lines named the same) and b) return the
hardware offset within the chip instead of the line object.
While not necessary to compile, the PyObject_HEAD macros look more
consistent with the rest of the code if they too have semicolons at the
end of the lines.
licensing: relicense C++ library code under LGPL-3.0-or-later
Using LGPL-2.1 for C++ library code is an issue raised several times on
the linux-gpio mailing list. Programs using C++ libraries often include
significant portions of code generated behind the scenes from C++ headers
(via templates, default implementations etc.).
Section 3 of LGPL-3.0 clarifies the use of code defined in or generated
from C++ headers so this changset proposes to use LGPL-3.0 for all C++
library code in libgpiod.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Acked-by: Kent Gibson <warthog618@gmail.com>
licensing: relicense non-library code under GPL-2.0-or-later
LGPL-2.1 is a license meant for shared libraries. Because I didn't know
any better I used it for all files in the repository, including programs
linking against libgpiod. The standard approach for many similar projects
is to use LGPL for library code and GPL for programs (and also Makefiles
and other files containing code or configuration).
Relicense all programs, tests, makefiles and autotools files under
GPL-2.0 or later.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Acked-by: Kent Gibson <warthog618@gmail.com>
In order to make the licensing situation of libgpiod clear and enable
easy reusing of the code, let's make all the files in the repository
compliant with the REUSE v3.0 specification.
In order to achieve that:
- put all used licenses into a separate LICENSES/ directory
- add SPDX license identifiers to all files that were missing them with
regular text files being licensed under CC-BY-SA-4.0, while files
containing code and configuration are licensed under GPL-2.0-or-later
- replace custom copyright texts with SPDX-FileCopyrightText
- update the gpio.h kernel uAPI header with the upstream version where
the SDPX license identifier was fixed to use 'GPL-2.0-only' variant
instead of the deprecated 'GPL-2.0'
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Acked-by: Kent Gibson <warthog618@gmail.com>
Kent Gibson [Mon, 15 Feb 2021 14:39:19 +0000 (15:39 +0100)]
bindings: python: fix uninitialized default_vals being passed to gpiod_LineBulk_request()
If "default_vals" is not provided in the kwds then default_vals are
passed uninitialized to gpiod_line_request_bulk(), so rename the
existing default_vals to vals and introduce a new default_vals that
points to vals, or NULL if no defaults have been passed.
Fixes: 96c524c4951c (bindings: implement python bindings) Reported-by: Pedro Botella <pbotella@gmail.com> Signed-off-by: Kent Gibson <warthog618@gmail.com> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
core: add the kernel uapi header to the repository
In order to avoid any problems with symbols missing from the host linux
kernel headers (for example: if current version of libgpiod supports
features that were added recently to the kernel but the host headers are
outdated and don't export required symbols) let's add the uapi header to
the repository and include it instead of the one in /usr/include/linux.
When we're reading the current bias setting of a line, it is already
disabled so the flag should be named as such. While BIAS_DISABLE would
technically be fine when modifying the setting, let's rename it to
BIAS_DISABLED too for consistency.
When inspecting the current bias setting of a GPIO line, the AS_IS name
of one of the possible values really means that the kernel GPIO subsystem
can't determine the bias setting because it didn't set it itself (e.g.
the hardware may have internally initialized pull-up or pull-down
resistors). In this case it's better to change the name to BIAS_UNKNOWN
to reflect that.
Unlike line direction - where input and output modes are equal, no signal
inversion (active-high) is the natural state of the line while active-low
is less likely. Let's drop the ACTIVE_STATE enum treewide and provide a
boolean property for lines - is_active_low() - to reflect that fact. This
function returning false means the line is "active-high".
treewide: remove helpers for opening chips by name & number
Helper wrappers around gpiod_chip_open() shouldn't really be part of
the core, low-level library. They assume that devtmpfs is mounted at
/dev and that GPIO chips follow the gpiochipX naming convention.
This changeset removes all variants of gpiod_chip_open() other than
the one taking the path as argument. We're doing this treewide so
C++ and Python bindings lose the 'how' argument that currently allows
to change the way the chips are opened by the chip's constructors or
the open() method in C++.
The gpio-tools programs still support opening chips by number, name
and path but they implement this functionality locally rather than
using the library code.
The test case for requesting multiple lines exposed by different chips
has never been correct. The request call does indeed fail with EINVAL
but now that we've disallowed adding lines from different chips to
the same bulk object, this happens only because we're using a wrong
constant in the flags field of the request structure.
Remove the entire test as it's no longer required.
Chip iterators require the user to have permission to access all GPIO
chips. They also don't take into account symbolic links. In general
they're badly designed so remove them treewide in favor of scanning /dev
manually using the provided gpiod_is_gpiochip_device() helper.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
GPIO line names are not unique and the library has been incorrectly
making such assumption in v1.x series. We've already dropped interfaces
that would be too complicated to maintain when taking this into account.
Let's now rework the remaming API. This introduces a new function to the
C API: gpiod_chip_find_line_unique() which assumes that the line name is
unique and signals an error if it's not. The previous
gpiod_chip_find_line() function now returns a bulk object containing all
matching lines.
Python and C++ bindings are updated: their find_line() functions return
bulk objects (or an ::std::vector> too now and they take an additional
argument specifying whether we're looking for a unique line or not.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
GPIO line names are not unique. Looking up multiple lines by names would
require us to return a list of matching lines for every name. We're
simplifying the library API so drop this interface treewide.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Global line lookup doesn't really work correctly because GPIO line names
are not unique. We'd have to return a list of matching lines. Also: not
all chips may be accessible by user in which case the chip iterator will
fail. We'll soon be removing chip iterators entirely so for now drop the
global line lookup and let users iterate over chips themselves.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Chip labels are not unique - opening chips by label may lead to errors
or to ignoring chips with duplicate labels. Users can easily implement
chip lookup by label themselves so remove this part from the core library
and all bindings.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Hand-crafted iterators don't make much sense in C and impose an
additional layer of memory allocation and resource releasing. Remove
the line iterators from the core C library.
We're leaving the iterators where they make sense: in C++ and Python
bindings but we convert them to using other means of keeping track of
lines.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
The limit of 64 lines max per bulk object is wrong. We may want to
retrieve all lines from a chip exporting more than 64. We'll be reducing
the role of bulk objects soon so drop this limit now.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
We'll be dropping chip iterators treewide. Instead we'll encourage
scanning /dev for GPIO chip devices. Exporting this function allows
users to easily check if given file represents a GPIO chip character
device.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
bindings: cxx: check for error from gpiod_line_bulk_new()
We call gpiod_line_bulk_new() in C++ bindings but never check its return
value. This function can fail so add a private method to line_bulk that
calls it and throws an exception if it returns NULL.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Current implementation of struct gpiod_line_bulk uses stack memory
excessively. The structure is big: it's an array 64 pointers + 4 bytes
size. That amounts to 260 bytes on 32-bit and 516 bytes on 64-bit
architectures respectively. It's also used everywhere as all functions
dealing with single lines eventually end up calling bulk counterparts.
The rework addresses it by making the bulk structure opaque and
providing appropriate interfaces for library users while retaining a way
for internal users to allocate single line bulks on the stack.
The macro-based loop has been removed. In its place we provide a function
iterating over all lines held by a bulk and calling the provided callback
function for each line.
Since bulk operations can now fail, a bunch of test-cases has been added
to cover the relevant code.
While at it: using the word offset both when referring to line's HW
offset in a chip as well as the offset in a bulk leads to confusion.
This patch renames the bulk offset to index.
Some additional improvements to the patch by:
Kent Gibson <warthog618@gmail.com>
bindings: cxx: demote the line's parent chip reference to a weak_ptr
Currently the line object has the power to control the parent chip's
lifetime because it stores a hard reference (in the form of a shared
pointer) to the underlying struct gpiod_chip. This is wrong from the
relationship point-of-view - the chip should control the exposed lines,
not the other way around.
Demote the parent reference to a weak_ptr. Introduce a sub-class that
allows line and line_bulk objects to lock the chip by temporarily
converting this weak_ptr to a full shared_ptr - this way we don't risk
dropping the last reference to the parent chip when the line is calling
the underlying library functions. Chip deleted during that time will
expire right after the concerned line method returns.
This requires an API change - the global find_line() function now
returns a <line, chip> pair so that the caller gets the chance to grab
the chip's reference.
treewide: make linux v5.10 a hard requirement for libgpiod
The library now uses v2 of the GPIO uAPI. The new user interface is
scheduled for release as part of linux v5.10. Linux v5.10-rc1 is now
tagged so make v5.10 headers a requirement for the build and update
all tests to check for the correct version.
TODO: add a task for replacing chrono::duration with chrono::time_point
We should store event timestamps in C++ bindings in
::std::chrono::time_point objects rather than in
::std::chrono::duration. Add a task for that to TODO.
Suggested-by: Helmut Grohne <helmut.grohne@intenta.de> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Kent Gibson [Wed, 14 Oct 2020 11:30:52 +0000 (19:30 +0800)]
core: Basic port to uAPI v2
Port existing implementation from GPIO uAPI v1 to v2.
The libgpiod external interface remains unchanged, only the internal
implementation switches from uAPI v1 to v2.
This is a minimal port - uAPI v2 features are not used, only the
uAPI v1 calls are switched to the v2 equivalent.
Signed-off-by: Kent Gibson <warthog618@gmail.com> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Kent Gibson [Wed, 14 Oct 2020 03:45:50 +0000 (11:45 +0800)]
bindings: cxx: tests: rename freq parameter to period_ms
The freq field of struct gpiod_test_event_thread is actually used as a
period measured in milliseconds, so rename it to period_ms in the struct
and wherever it is used as a function parameter.
Signed-off-by: Kent Gibson <warthog618@gmail.com> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
In many test-cases we read/set values or try to poll for events after
a failed line request. Some tests even segfault because they don't check
returned values for NULL etc.