Having both --enable-tests configure option and the check make target
seems redundant and confusing. Especially since the tests won't even
run without appropriate permissions for /dev/gpiochipX anyway.
Remove the check target and the --enable-install-tests option. From now
on the tests - if enabled - are built as a regular program installed to
${prefix}/bin.
After recent changes the tests stopped working when other (non mockup)
GPIO chips are present in the system. The reason for that is broken
mapping of chip numbers to chip indexes. This patch fixes it.
tests: gpiomon: increase the time waiting for events
We no longer have influence over the type of generated events. We
always start with a rising edge-event and then get alternating edges.
We need to wait slightly longer to collect the events we're expecting
in one of the test cases.
tests: provide test_debugfs_get/set_value() helpers
Since linux v5.1 gpio-mockup simulates pull-up/down resistors for dummy
lines. The current pull can be set using debugfs. Since we can no longer
verify if the character device interface properly sets line values, the
debugfs interface now also allows to read line values. This way we can
verify if the ABI works correctly using different code paths.
Provide functions for reading and setting values of mockup GPIO lines.
Since linux v5.1 the debugfs path for gpio-mockup changed. Use the new
path both for the main directory as well as for the chip subdirectories
which no longer use the chip's label.
tests: don't allow to generate events of the same type subsequently
Since linux v5.1 the state of simulated lines is tracked by the kernel
and it's no longer possible to generate two subsequent events of the
same type (e.g. two rising edge events one after another). Drop the
event_type parameter from test_set_event() and adjust all users.
TODO: add a list of things to implement for feature-complete
Add a document listing major features I'd like to see in libgpiod to
make it more or less complete (not including of course the support for
any potential new features that the kernel may expose in the future).
David Kozub [Thu, 28 Mar 2019 22:49:23 +0000 (23:49 +0100)]
bindings: cxx: make operator bool() explicit
A non-explicit operator bool() is dangerous: It allows unwanted
conversion to integral types:
gpiod::chip c;
int i = c;
This is a trivial example, but more insidious effects are possible,
e.g. with std::set<gpiod::chip>, which would use the operator bool()
to implement element comparison, thus turning such set into a set that
has at most 2 elements: An invalid (false) element and just 1 valid
element:
std::set<gpiod::chip> s;
s.emplace();
s.emplace("/dev/gpiochip0");
s.emplace("/dev/gpiochip1");
// s.size() is still 2 even if both chips were opened!
Making the operator explicit disables this.
See e.g.
https://en.cppreference.com/w/cpp/language/implicit_conversion#The_safe_bool_problem
for more info on this.
Signed-off-by: David Kozub <zub@linux.fjfi.cvut.cz> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
David Kozub [Thu, 28 Mar 2019 23:27:28 +0000 (00:27 +0100)]
bindings: cxx: remove superfluous std::move
There is no need to use std::move on an r-value (e.g.
std::move(gpiod::chip())). Similarly, there is no need to use std::move
for returning a local variable as in:
T foo()
{
U local;
return std::move(local);
}
Not only it doesn't help, it actually inhibits named return value
optimization.
See e.g. https://isocpp.org/blog/2013/02/no-really-moving-a-return-value-is-easy-stackoverflow
Signed-off-by: David Kozub <zub@linux.fjfi.cvut.cz> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Currently we only support running the test cases for gpio-tools from
the top-level source directory. Some users want to install the test
executable and run the tests from other locations (/bin, /usr/bin or
custom path).
This patch makes the test suite look in the source tree path first,
then check the directory in which the program resides and last iterate
over all directories in $PATH.
We only do that once at the beginning and then reuse the path later.
Cc: Anders Roxell <anders.roxell@linaro.org> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Anders Roxell <anders.roxell@linaro.org> Tested-by: Anders Roxell <anders.roxell@linaro.org>
Anders Roxell [Fri, 15 Mar 2019 10:01:44 +0000 (11:01 +0100)]
tests: enable installing tests to bindir
Add an enable option to configure that allows to install the testing
binary to <prefix>/bindir.
Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
[Bartosz: trimmed the patch to fit the new approach] Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
The src directory containing lib and tools is not necessary and will
actually cause problems if we tried to add a new component to src/
which would depend on libraries from the bindings directory because it
(bindings) already depends on src/lib.
Simplify the directory structure. Move lib and tools to the root source
directory and update all relevant files. That way we can specify the
exact build order of components from the top source Makefile.am.
Currently the man page template used by help2man is not included in the
distribution tarball. This causes build failures on systems that
actually do have help2man in which case we rebuild the man pages
locally. Add template to EXTRA_DIST.
Return -1 and set errno to EINVAL if the number of lines specified in
any context-less helper is 0. This is done in addition to bailing out
when the number is higher than the maximum supported number of GPIO
lines. This fixes the segfaults that currently ocurr for num_lines == 0.
Martin Hundebøll [Mon, 25 Feb 2019 09:43:07 +0000 (10:43 +0100)]
gpiomon: add option to set line buffered output
Some applications call gpiomon in a sub process, in which case glibc
defaults to block buffered output on stdout. This makes the output
arrive to the calling process only when the (4kB) buffer is filled (or
when gpiomon exists), making the information obsolete and pretty much
useless.
Support such scenarios by adding a switch to configure line buffered
output on stdout. Similar switches are available in other applications
(e.g. `rsync`s --output argument).
Signed-off-by: Martin Hundebøll <martin@geanix.com>
[Bartosz:
- use setlinebuf() instead of setvbuf(),
- tweak the help string,
- move the setlinebuf() call directly into the optarg switch statement] Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
When defining enable arguments, we don't need a full if-else spanning
multiple lines. We only care about the 'true' value, so pull the
relevant code into a single line.
Unify the header includes by ordering them alphabetically and always
having local headers in a second group below the global ones (separated
by a newline).
Doxygen and python documentation are briefly mentioned in the BINDINGS
section but there's no word about the core C API and automatically
generated man pages.
Add a separate section to the README file describing the process of
generating html doxygen output, python help strings and man pages for
gpio-tools.
doc: add automatically generated man pages for gpio-tools
Extend the build files to automatically generate man pages for
gpio-tools using help2man if it's present in the system and we're not
cross-compiling (as the built programs must be executable for help2man
to work).
bindings: python: add support for 'default_val' in Line.request()
Until now Line.request() only took 'default_vals' argument which was
passed down directly to LineBulk.request() internally. This meant that
even when requesting a single line in output mode, the default value
had to be passed in a sequence.
Add support for the 'default_val' argument which makes it possible to
specify the default value as an integer. The previous 'default_vals'
argument is still supported, but the two cannot be passed at the same
time.
Documentation for default_vals is removed, as it's now deprecated for
Line.request().
Since commit fa38869b0161 ("gpiolib: Don't support irq sharing for
userspace") in the kernel, the test case veryfing correct ignoring
of edge events is failing. It will take a while until it will be
fixed upstream so remove this test for now.
bindings: cxx: do not initialize a chip's shared_ptr with nullptr
A shared_ptr initialized with nullptr will still call the deleter which
causes a NULL-pointer dereference if we create a chip_iter when there
are no GPIO chips in the system.
Only initialize the current chip object in chip_iter if
gpiod_chip_iter_next_noclose() returned a valid pointer.
Signed-off-by: Patrick Boettcher <p@yai.se>
[Bartosz:
- tweaked the commit message
- use std::move when assigning the chip object] Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
There's a common misconception about the way the character device
works. Some users expect line states to be driven as desired even
after gpioset exits. Add a note about that to the help text to avoid
further confusion.
Gasper Zejn [Fri, 23 Feb 2018 13:51:19 +0000 (14:51 +0100)]
doc: C API documentation fixes
Fix a couple problems in doxygen documentation of the C API.
(Unfortunately no Signed-off-by tag from the submitter...)
[Bartosz: added a proper commit message] Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
So far the tests have been executed on a Debian 9 machine with libudev
provided by systemd 232 - everything always worked fine. However
running them on a system with systemd 237 uncovered a bug in the
testing framework.
It turned out that on newer versions the ignored 'remove' events linger
somewhere in the pipeline and get read by subsequent test cases causing
erroneous chip naming and breaking tests.
Check the action string for udev device objects and only care about
those being added.
Not including <sys/sysmacros.h> causes the following error on ARM:
core.c: In function ‘is_gpiochip_cdev’:
core.c:116:4: warning: implicit declaration of function ‘major’ [-Wimplicit-function-declaration]
major(statbuf.st_rdev), minor(statbuf.st_rdev));
^~~~~
core.c:116:28: warning: implicit declaration of function ‘minor’; did you mean ‘mknod’? [-Wimplicit-function-declaration]
major(statbuf.st_rdev), minor(statbuf.st_rdev));
^~~~~
mknod
It wasn't spotted earlier since it builds fine on x86-64. Add the
missing include.
API: mark context-less event loop functions as deprecated
Mark gpiod_ctxless_event_loop() and gpiod_ctxless_event_loop_multiple()
as deprecated. Those functions suffer from an issue where HW may not
allow setting up both rising and falling egde interrupts. All users
have been converted to using the new event monitor helpers.
tests: ctxless: switch to using the event monitor routines
Use gpiod_ctxless_event_monitor() and
gpiod_ctxless_event_monitor_multiple() instead of
gpiod_ctxless_event_loop() and gpiod_ctxless_event_loop_multiple()
respectively.
gpiomon: switch to using gpiod_ctxless_event_monitor_multiple()
Switch to using the new context-less routine for event monitoring. We
can now simplify the event callback as there's no need anymore to
check the event type in the handler.
Current implementation of gpiod_ctxless_event_loop() (and its variant
for multiple lines) always requests GPIO lines for listening for both
rising and falling edge events. This causes a problem when the
underlying hardware doesn't allow this.
It can e.g. result in the following error raised by the interrupt
controller:
For the sake of backward compatibility we're leaving the old
implementation in place and provide two new routines that that take an
additional parameter allowing users to specify the events libgpiod
should listen for.
This patch adds proper include file to fix FTBFS issue in
gpiod_cxx_tests.cpp, please see below error.
gpiod_cxx_tests.cpp:29:19: note: 'std::function' is defined in header '<functional>'; did you forget to '#include <functional>'?
gpiod_cxx_tests.cpp:26:1:
+#include <functional>
Signed-off-by: SZ Lin (林上智) <sz.lin@moxa.com>
[Bartosz: tweaked the commit message] Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
bindings: python: bail-out if the line was not found in gpiofind.py
Currently we're not checking if the object returned from
gpiod.fine_line() is None which results in an attribute error being
raised when we try to call line methods on a non-line object.
Add an if and bail-out with an error code if the line with given name
was not found.
bindings: python: fix gpiod_Chip_find_lines() for nonexistent lines
Currently if we call gpiod_Chip_find_lines() with some names that
cannot be looked up, we end up getting an exception from the LineBulk
object's constructor (because None is not a Line and LineBulk can only
hold Line objects).
Fix the behavior of gpiod_Chip_find_lines() for nonexistent lines by
raising an explicit exception if the underlying gpiod_Chip_find_line()
call returns None. Also: add a relevant test case.
bindings: python: examples: close chip objects where needed
Unlike the C++ bindings: we can't expect the python runtime to call
the Chip object's destructor when all references are dropped. We need
to close each chip explicitly. Either call the close() method directly
or use controlled execution in all examples.
bindings: python: fix tp_dealloc callbacks in all objects
We have a significant memory leak in the current implementation as we
don't call PyObject_Del() as the last action in tp_dealloc callbacks.
From tp_dealloc's documentation:
---
The destructor function should free all references which the instance
owns, free all memory buffers owned by the instance (using the freeing
function corresponding to the allocation function used to allocate the
buffer), and finally (as its last action) call the type’s tp_free
function.
---
PyObject_Del() will internally call the tp_free callback of the type.
Add a call to it as the last action in every destructor.
We can instantiate an object of a type by "calling" it's type structure
using PyObject_CallObject(). It will internally call the constructor so
use it to shrink the code.
bindings: python: fix the default_vals argument in line requests
We're assigning the wrong local variable in PyArg_ParseTupleAndKeywords()
which results in not honoring the default_vals argument. Fix the
LineBulk.request() implementation.
bindings: python: move gpiod_ChipIsClosed() to the top of gpiodmodule.c
Unlike the other two helpers that are still declared at the top of the
source file - this routine doesn't need to know any gpiod-specific type
so move it up and remove the prototype.
bindings: python: provide a helper for calling methods with python args
Wrap the calls to PyObject_GetAttrString() and PyObject_Call() in
a single helper that allows to call a python method and pass it the
args and kwds tuples directly as received from the interpreter.
PyList_GetItem() returns a borrowed reference so we need to increase
the reference count on the returned object before DECREF'ing the list
object itself
This fixes random 'free(): invalid pointer' errors.
On some architectures we get a 'comparison between signed and unsigned
integer' warning when building python bindings. Fix it by changing the
type of the variable used for offset to unsigned int.
Where it's impossible to use PyObject_CallMethod() (e.g. when we want
to pass args and kwargs unchanged to the method being called), use
a combination of PyObject_GetAttrString() and PyObject_Call().
So far we rely on cpython's reference counting for closing the GPIO
chips and freeing the underlying resources. This is however wrong.
Python doesn't guarantee anything regarding the lifetime of an object.
Provide a method for closing the underlying chip handle and add
relevant checks to all methods using the resources associated with
a GPIO chip, so that we raise an error should the user use a chip
after closing it.