* [libgpiod] reading multiple lines after edge event
@ 2020-06-15 19:39 Gerrit Wyen
2020-06-16 18:11 ` Andy Shevchenko
2020-06-17 1:57 ` Kent Gibson
0 siblings, 2 replies; 4+ messages in thread
From: Gerrit Wyen @ 2020-06-15 19:39 UTC (permalink / raw)
To: linux-gpio
Hi,
can someone explain the following behavior and whether it is a bug?
When reading two lines at once via get_values() in response to an edge
event I only receive the correct value for the first line (second line
is high during the test but always reported as low).
See example code below:
lines.request({
“gpiotest”, ::gpiod::line_request::EVENT_BOTH_EDGES,
0,
});
auto events = lines.event_wait(::std::chrono::seconds(10));
if (events) {
auto values = lines.get_values();
for (auto& it: values) {
::std::cout << it;
}
}
However reading the same lines via get_value() one by one after the
event works correctly. Like so:
for (auto& it: lines) { ::std::cout << it.get_value(); }
Also, when reading them without waiting for the event with
line_request::DIRECTION_INPUT the correct values are returned by
get_values() as well as by get_value().
This behavior was tested on multiple different devices.
thanks,
Gerrit
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [libgpiod] reading multiple lines after edge event
2020-06-15 19:39 [libgpiod] reading multiple lines after edge event Gerrit Wyen
@ 2020-06-16 18:11 ` Andy Shevchenko
2020-06-17 1:57 ` Kent Gibson
1 sibling, 0 replies; 4+ messages in thread
From: Andy Shevchenko @ 2020-06-16 18:11 UTC (permalink / raw)
To: Gerrit Wyen, Bartosz Golaszewski; +Cc: open list:GPIO SUBSYSTEM
On Mon, Jun 15, 2020 at 10:45 PM Gerrit Wyen <ml@ionscale.com> wrote:
>
> Hi,
>
> can someone explain the following behavior and whether it is a bug?
>
> When reading two lines at once via get_values() in response to an edge
> event I only receive the correct value for the first line (second line
> is high during the test but always reported as low).
> See example code below:
>
> lines.request({
> “gpiotest”, ::gpiod::line_request::EVENT_BOTH_EDGES,
> 0,
> });
>
> auto events = lines.event_wait(::std::chrono::seconds(10));
> if (events) {
> auto values = lines.get_values();
> for (auto& it: values) {
> ::std::cout << it;
> }
> }
>
> However reading the same lines via get_value() one by one after the
> event works correctly. Like so:
>
> for (auto& it: lines) { ::std::cout << it.get_value(); }
>
>
> Also, when reading them without waiting for the event with
> line_request::DIRECTION_INPUT the correct values are returned by
> get_values() as well as by get_value().
>
> This behavior was tested on multiple different devices.
One side question: do you have kernel 64-bit and user space 64-bit, or?
Also, can you provide versions of the kernel and libgpiod, if you are
using latter?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [libgpiod] reading multiple lines after edge event
2020-06-15 19:39 [libgpiod] reading multiple lines after edge event Gerrit Wyen
2020-06-16 18:11 ` Andy Shevchenko
@ 2020-06-17 1:57 ` Kent Gibson
2020-06-17 15:40 ` Gerrit Wyen
1 sibling, 1 reply; 4+ messages in thread
From: Kent Gibson @ 2020-06-17 1:57 UTC (permalink / raw)
To: Gerrit Wyen; +Cc: linux-gpio
On Mon, Jun 15, 2020 at 09:39:45PM +0200, Gerrit Wyen wrote:
> Hi,
>
> can someone explain the following behavior and whether it is a bug?
>
> When reading two lines at once via get_values() in response to an edge event
> I only receive the correct value for the first line (second line is high
> during the test but always reported as low).
> See example code below:
>
> lines.request({
> “gpiotest”, ::gpiod::line_request::EVENT_BOTH_EDGES,
> 0,
> });
>
> auto events = lines.event_wait(::std::chrono::seconds(10));
> if (events) {
> auto values = lines.get_values();
> for (auto& it: values) {
> ::std::cout << it;
> }
> }
>
> However reading the same lines via get_value() one by one after the event
> works correctly. Like so:
>
> for (auto& it: lines) { ::std::cout << it.get_value(); }
>
>
> Also, when reading them without waiting for the event with
> line_request::DIRECTION_INPUT the correct values are returned by
> get_values() as well as by get_value().
>
> This behavior was tested on multiple different devices.
>
>
I have written some test cases and can confirm that behaviour
with libgpiod v1.5.
When you request the lines with DIRECTION_INPUT, libgpiod is using a
linehandle (which works), but with EVENT_BOTH_EDGES it is using
a collection of linevents (which doesn't).
I would consider that a bug - linehandles (lines without edge detection)
and lineevents (lines with edge detection) are treated differently
in the GPIO uAPI and libgpiod should be hiding that from you - and is
failing to do that.
The issue here is that the underlying function that retrieves the values,
gpiod_line_get_value_bulk, assumes it is dealing with a linehandle
that can be read in bulk by the kernel, not a collection of lineevents
that must be read individually, so it is only getting the value of the
first line in the set. It should be getting the event lines
individually, as you are, and collecting those values into the response.
Until there is a fix, the workaround is to read the event lines
individually - as you have already discovered.
Cheers,
Kent.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [libgpiod] reading multiple lines after edge event
2020-06-17 1:57 ` Kent Gibson
@ 2020-06-17 15:40 ` Gerrit Wyen
0 siblings, 0 replies; 4+ messages in thread
From: Gerrit Wyen @ 2020-06-17 15:40 UTC (permalink / raw)
To: Kent Gibson; +Cc: linux-gpio
Am 17.06.20 um 03:57 schrieb Kent Gibson:
> On Mon, Jun 15, 2020 at 09:39:45PM +0200, Gerrit Wyen wrote:
>> Hi,
>>
>> can someone explain the following behavior and whether it is a bug?
>>
>> When reading two lines at once via get_values() in response to an edge event
>> I only receive the correct value for the first line (second line is high
>> during the test but always reported as low).
>> See example code below:
>>
>> lines.request({
>> “gpiotest”, ::gpiod::line_request::EVENT_BOTH_EDGES,
>> 0,
>> });
>>
>> auto events = lines.event_wait(::std::chrono::seconds(10));
>> if (events) {
>> auto values = lines.get_values();
>> for (auto& it: values) {
>> ::std::cout << it;
>> }
>> }
>>
>> However reading the same lines via get_value() one by one after the event
>> works correctly. Like so:
>>
>> for (auto& it: lines) { ::std::cout << it.get_value(); }
>>
>>
>> Also, when reading them without waiting for the event with
>> line_request::DIRECTION_INPUT the correct values are returned by
>> get_values() as well as by get_value().
>>
>> This behavior was tested on multiple different devices.
>>
>>
>
> I have written some test cases and can confirm that behaviour
> with libgpiod v1.5.
>
> When you request the lines with DIRECTION_INPUT, libgpiod is using a
> linehandle (which works), but with EVENT_BOTH_EDGES it is using
> a collection of linevents (which doesn't).
>
> I would consider that a bug - linehandles (lines without edge detection)
> and lineevents (lines with edge detection) are treated differently
> in the GPIO uAPI and libgpiod should be hiding that from you - and is
> failing to do that.
>
> The issue here is that the underlying function that retrieves the values,
> gpiod_line_get_value_bulk, assumes it is dealing with a linehandle
> that can be read in bulk by the kernel, not a collection of lineevents
> that must be read individually, so it is only getting the value of the
> first line in the set. It should be getting the event lines
> individually, as you are, and collecting those values into the response.
>
> Until there is a fix, the workaround is to read the event lines
> individually - as you have already discovered.
>
> Cheers,
> Kent.
>
Thanks a lot for the quick response.
I applied your patch and it fixed the issue.
best regards,
Gerrit
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-06-17 15:40 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-06-15 19:39 [libgpiod] reading multiple lines after edge event Gerrit Wyen
2020-06-16 18:11 ` Andy Shevchenko
2020-06-17 1:57 ` Kent Gibson
2020-06-17 15:40 ` Gerrit Wyen
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.