All of lore.kernel.org
 help / color / mirror / Atom feed
* GPIO Bulk Request Problem
@ 2021-09-22 16:26 Kenneth Sloat
  2021-09-24  9:57 ` Bartosz Golaszewski
  0 siblings, 1 reply; 5+ messages in thread
From: Kenneth Sloat @ 2021-09-22 16:26 UTC (permalink / raw)
  To: linux-gpio; +Cc: Kenneth Sloat

Hello,

I am using libgpiod v1.4.1 and am having trouble using a bulk request of gpio lines as outputs from a chip. I am using the C++ bindings. I have confirmed that I can individually request lines and set them as expected. However, if I use the bulk request, while I get the expected number of lines (and defaulted value is set correctly), iterating through them (with array operator in this case) and trying to set the values is not working as expected. I find that for every index/position, line 0 is the one being toggled.

A simple example is below:

    gpiod::chip *mychip;

    mychip = new gpiod::chip("1");

    gpiod::line_bulk lines = mychip->get_all_lines();
    lines.request({std::string("gpio-test"),
        gpiod::line_request::DIRECTION_OUTPUT, 0});

    for (unsigned int i = 0; i < lines.size(); i++) {
        printf("Set line %d\n", i);
        lines[i].set_value(1);
        usleep(1000 * 1000);
        printf("Clear line %d\n", i);
        lines[i].set_value(0);
        usleep(1000 * 1000);
        printf("\n");
    }

    return 0;

Not sure if this is a usage problem on my part or an actual issue.

Thanks

Sincerely,
Ken Sloat

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: GPIO Bulk Request Problem
  2021-09-22 16:26 GPIO Bulk Request Problem Kenneth Sloat
@ 2021-09-24  9:57 ` Bartosz Golaszewski
  2021-09-24 12:25   ` Kenneth Sloat
  0 siblings, 1 reply; 5+ messages in thread
From: Bartosz Golaszewski @ 2021-09-24  9:57 UTC (permalink / raw)
  To: Kenneth Sloat; +Cc: linux-gpio

On Wed, Sep 22, 2021 at 6:27 PM Kenneth Sloat <ksloat@designlinxhs.com> wrote:
>
> Hello,
>
> I am using libgpiod v1.4.1 and am having trouble using a bulk request of gpio lines as outputs from a chip. I am using the C++ bindings. I have confirmed that I can individually request lines and set them as expected. However, if I use the bulk request, while I get the expected number of lines (and defaulted value is set correctly), iterating through them (with array operator in this case) and trying to set the values is not working as expected. I find that for every index/position, line 0 is the one being toggled.
>
> A simple example is below:
>
>     gpiod::chip *mychip;
>
>     mychip = new gpiod::chip("1");

Why would you need to allocate it with new?

>
>     gpiod::line_bulk lines = mychip->get_all_lines();
>     lines.request({std::string("gpio-test"),
>         gpiod::line_request::DIRECTION_OUTPUT, 0});
>
>     for (unsigned int i = 0; i < lines.size(); i++) {
>         printf("Set line %d\n", i);
>         lines[i].set_value(1);
>         usleep(1000 * 1000);
>         printf("Clear line %d\n", i);
>         lines[i].set_value(0);
>         usleep(1000 * 1000);
>         printf("\n");
>     }
>
>     return 0;
>
> Not sure if this is a usage problem on my part or an actual issue.
>

I'll see if I can confirm the behavior here but it looks like a bug indeed.

Bart

> Thanks
>
> Sincerely,
> Ken Sloat

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: GPIO Bulk Request Problem
  2021-09-24  9:57 ` Bartosz Golaszewski
@ 2021-09-24 12:25   ` Kenneth Sloat
  2021-10-07 19:14     ` Bartosz Golaszewski
  0 siblings, 1 reply; 5+ messages in thread
From: Kenneth Sloat @ 2021-09-24 12:25 UTC (permalink / raw)
  To: Bartosz Golaszewski; +Cc: linux-gpio, Kenneth Sloat

Hi Bart,

On Wed, Sep 22, 2021 at 6:27 PM Kenneth Sloat <ksloat@designlinxhs.com> wrote:
>>
>> Hello,
>>
>> I am using libgpiod v1.4.1 and am having trouble using a bulk request of gpio lines as outputs from a chip. I am using the C++ bindings. I have confirmed that I can individually request lines and set them as expected. However, if I use the bulk request, while I get the expected number of lines (and defaulted value is set correctly), iterating through them (with array operator in this case) and trying to set the values is not working as expected. I find that for every index/position, line 0 is the one being toggled.
>>
>> A simple example is below:
>>
>>     gpiod::chip *mychip;
>>
>>     mychip = new gpiod::chip("1");

> Why would you need to allocate it with new?

It's just how I chose to throw the example together.

>>
>>     gpiod::line_bulk lines = mychip->get_all_lines();
>>     lines.request({std::string("gpio-test"),
>>         gpiod::line_request::DIRECTION_OUTPUT, 0});
>>
>>     for (unsigned int i = 0; i < lines.size(); i++) {
>>         printf("Set line %d\n", i);
>>         lines[i].set_value(1);
>>         usleep(1000 * 1000);
>>         printf("Clear line %d\n", i);
>>         lines[i].set_value(0);
>>         usleep(1000 * 1000);
>>         printf("\n");
>>     }
>>
>>     return 0;
>>
>> Not sure if this is a usage problem on my part or an actual issue.
>>

> I'll see if I can confirm the behavior here but it looks like a bug indeed.

> Bart

Thanks Bart. If you use individual requests to the GPIOs as outputs first, use can still use the index operator (or iterator) on a line_bulk object to individually set the LEDs. It doesn't work when you only use the request through this object though:
    gpiod::line_bulk lines = mychip->get_all_lines();
        lines.request(......

> Thanks
>
> Sincerely,
> Ken Sloat

Thanks

Sincerely,
Ken Sloat

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: GPIO Bulk Request Problem
  2021-09-24 12:25   ` Kenneth Sloat
@ 2021-10-07 19:14     ` Bartosz Golaszewski
  2021-10-07 19:22       ` Kenneth Sloat
  0 siblings, 1 reply; 5+ messages in thread
From: Bartosz Golaszewski @ 2021-10-07 19:14 UTC (permalink / raw)
  To: Kenneth Sloat; +Cc: linux-gpio

On Fri, Sep 24, 2021 at 2:25 PM Kenneth Sloat <ksloat@designlinxhs.com> wrote:
>
> Hi Bart,
>
> On Wed, Sep 22, 2021 at 6:27 PM Kenneth Sloat <ksloat@designlinxhs.com> wrote:
> >>
> >> Hello,
> >>
> >> I am using libgpiod v1.4.1 and am having trouble using a bulk request of gpio lines as outputs from a chip. I am using the C++ bindings. I have confirmed that I can individually request lines and set them as expected. However, if I use the bulk request, while I get the expected number of lines (and defaulted value is set correctly), iterating through them (with array operator in this case) and trying to set the values is not working as expected. I find that for every index/position, line 0 is the one being toggled.
> >>
> >> A simple example is below:
> >>
> >>     gpiod::chip *mychip;
> >>
> >>     mychip = new gpiod::chip("1");
>
> > Why would you need to allocate it with new?
>
> It's just how I chose to throw the example together.
>
> >>
> >>     gpiod::line_bulk lines = mychip->get_all_lines();
> >>     lines.request({std::string("gpio-test"),
> >>         gpiod::line_request::DIRECTION_OUTPUT, 0});
> >>
> >>     for (unsigned int i = 0; i < lines.size(); i++) {
> >>         printf("Set line %d\n", i);
> >>         lines[i].set_value(1);
> >>         usleep(1000 * 1000);
> >>         printf("Clear line %d\n", i);
> >>         lines[i].set_value(0);
> >>         usleep(1000 * 1000);
> >>         printf("\n");
> >>     }
> >>
> >>     return 0;
> >>
> >> Not sure if this is a usage problem on my part or an actual issue.
> >>
>
> > I'll see if I can confirm the behavior here but it looks like a bug indeed.
>
> > Bart
>
> Thanks Bart. If you use individual requests to the GPIOs as outputs first, use can still use the index operator (or iterator) on a line_bulk object to individually set the LEDs. It doesn't work when you only use the request through this object though:
>     gpiod::line_bulk lines = mychip->get_all_lines();
>         lines.request(......
>
> > Thanks
> >
> > Sincerely,
> > Ken Sloat
>
> Thanks
>
> Sincerely,
> Ken Sloat

So I took a look at this and unfortunately you hit one of the major
issues with libgpiod v1 and something that will be thoroughly
addressed in v2. When you make a bulk request, all the lines share a
single file descriptor. That means that any ioctl() operates on sets
of lines rather than single lines. The only fix for that would be to
force requesting every line on its own. Unfortunately the only "fix"
to your problem is to always use the bulk object. Otherwise the single
line cannot know it's being used separately.

In v2 we're addressing it by associating a request explicitly with a
set of lines (can be a single line) and never allowing this kind of
situation.

Sorry for the inconvenience - I didn't know any better at the time.

Bart

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: GPIO Bulk Request Problem
  2021-10-07 19:14     ` Bartosz Golaszewski
@ 2021-10-07 19:22       ` Kenneth Sloat
  0 siblings, 0 replies; 5+ messages in thread
From: Kenneth Sloat @ 2021-10-07 19:22 UTC (permalink / raw)
  To: Bartosz Golaszewski; +Cc: linux-gpio, Kenneth Sloat

Hi Bart,

On Fri, Sep 24, 2021 at 2:25 PM Kenneth Sloat <ksloat@designlinxhs.com> wrote:
>
> Hi Bart,
>
> On Wed, Sep 22, 2021 at 6:27 PM Kenneth Sloat <ksloat@designlinxhs.com> wrote:
> >>
> >> Hello,
> >>
> >> I am using libgpiod v1.4.1 and am having trouble using a bulk request of gpio lines as outputs from a chip. I am using the C++ bindings. I have confirmed that I can individually request lines and set them as expected. However, if I use the bulk request, while I get the expected number of lines (and defaulted value is set correctly), iterating through them (with array operator in this case) and trying to set the values is not working as expected. I find that for every index/position, line 0 is the one being toggled.
> >>
> >> A simple example is below:
> >>
> >>     gpiod::chip *mychip;
> >>
> >>     mychip = new gpiod::chip("1");
>
> > Why would you need to allocate it with new?
>
> It's just how I chose to throw the example together.
>
> >>
> >>     gpiod::line_bulk lines = mychip->get_all_lines();
> >>     lines.request({std::string("gpio-test"),
> >>         gpiod::line_request::DIRECTION_OUTPUT, 0});
> >>
> >>     for (unsigned int i = 0; i < lines.size(); i++) {
> >>         printf("Set line %d\n", i);
> >>         lines[i].set_value(1);
> >>         usleep(1000 * 1000);
> >>         printf("Clear line %d\n", i);
> >>         lines[i].set_value(0);
> >>         usleep(1000 * 1000);
> >>         printf("\n");
> >>     }
> >>
> >>     return 0;
> >>
> >> Not sure if this is a usage problem on my part or an actual issue.
> >>
>
> > I'll see if I can confirm the behavior here but it looks like a bug indeed.
>
> > Bart
>
> Thanks Bart. If you use individual requests to the GPIOs as outputs first, use can still use the index operator (or iterator) on a line_bulk object to individually set the LEDs. It doesn't work when you only use the request through this object though:
>     gpiod::line_bulk lines = mychip->get_all_lines();
>         lines.request(......
>
> > Thanks
> >
> > Sincerely,
> > Ken Sloat
>
> Thanks
>
> Sincerely,
> Ken Sloat

> So I took a look at this and unfortunately you hit one of the major
issues with libgpiod v1 and something that will be thoroughly
addressed in v2. When you make a bulk request, all the lines share a
single file descriptor. That means that any ioctl() operates on sets
of lines rather than single lines. The only fix for that would be to
force requesting every line on its own. Unfortunately the only "fix"
to your problem is to always use the bulk object. Otherwise the single
line cannot know it's being used separately.

> In v2 we're addressing it by associating a request explicitly with a
set of lines (can be a single line) and never allowing this kind of
situation.

> Sorry for the inconvenience - I didn't know any better at the time.

> Bart

No problem, and I already worked around it using other methods, but I appreciate you following up with me on the matter and I'll keep this in mind in the future.

Sincerely,
Ken Sloat

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-10-07 19:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-22 16:26 GPIO Bulk Request Problem Kenneth Sloat
2021-09-24  9:57 ` Bartosz Golaszewski
2021-09-24 12:25   ` Kenneth Sloat
2021-10-07 19:14     ` Bartosz Golaszewski
2021-10-07 19:22       ` Kenneth Sloat

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.