Re: [questions] : gpiolib and gpioset behaviour

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Apr 26, 2024 at 04:07 AM, Kent Gibson wrote :
> On Mon, Apr 22, 2024 at 06:49:05PM +0200, Gilles BULOZ wrote:
>> On Mon, Apr 22, 2024 at 3:55 PM Bartosz Golaszewski wrote :
>>> On Mon, Apr 22, 2024 at 2:44 PM Gilles BULOZ <gilles.buloz@xxxxxxxxxxx> wrote:
>>>>
>>>> Hi Bartosz,
>>>>
>>>> Several years after our discussions about GPIOs, some things are still unclear
>>>> to me.
>>>>
>>>> 1 - The gpioset command has this in its help : "Note: the state of a GPIO line
>>>> controlled over the character device reverts to default when the last process
>>>> referencing the file descriptor representing the device file exits. This means
>>>> that it's wrong to run gpioset, have it exit and expect the line to continue
>>>> being driven high or low. It may happen if given pin is floating but it must
>>>> be interpreted as undefined behavior." But up to now I've never seen such
>>>> behaviour and I'm glad to have the GPIO set by gpioset keep their state once
>>>> the command exits. Is reverting to default an optional behaviour in the GPIO
>>>> chip driver, or in the gpiolib stack ?
>>>>
>>>
>>> This behavior is driver-specific. Meaning: you're in-kernel GPIO
>>> driver may actually retain the state.
>>>
>>
>> Which method should the driver implement to restore the state on GPIO when the
>> last process referencing the character device exits ?
>>
>>>> 2 - I've recently wrote a GPIO driver for an I2C FPGA design having ~112 GPIOs
>>>> and wanted to use get_multiple() and set_multiple to have more efficent
>>>> accesses, but realized that the line number was limited to 63 because of the
>>>> unsigned long mask/bits. But I've noticed that working on a line number >= 64
>>>> was unexpectedly calling these methods with a mask at 0 instead of calling
>>>> get/set methods, and that the only way to have things working was to not
>>>> define get_multiple/set_multiple but only get/set. Is it the expected
>>>> behaviour ?
>>>> At the end I've split the GPIOs into two banks (first with 64 and second with
>>>> 48 GPIOs) to be able to use get_multiple/set_multiple.
>>>>
>>>
>>> Please use libgpiod v2. That won't help you with the max requested
>>> line limit but at least it's more modern API and actively developed.
>>>
>>
>
> I suspect you are referring to gpiolib here - the mask in gc->get_multiple()
> being unsigned long*.
>
> The uAPI that libgpiod uses is limited to 64 lines per request, but that is
> only relevant if you want to request more than 64 lines at once from userspace
> (you would have to break that into two requests to access all 112 lines).
>
> Note that the mask in gc->get_multiple() is unsigned long*, so it is a
> pointer to an array of unsigned long.  Its width is not limited by
> unsigned long, but by the bits parameter.  In your case the mask you pass
> should contain multiple unsigned longs to achieve 112 bits.
> Refer to gpiod_get_array_value_complex() for an example of building bitmap
> masks to pass to gc->get_multiple(), in that case via
> gpio_chip_get_multiple().
>

I was refering the get_multiple/set_multiple callbacks in struct gpio_chip
that are defined like this :
 int (*get_multiple)(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits);
 void (*set_multiple)(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits);
With some debug in my GPIO chip driver implementing these functions, I saw that
the bits set in "mask" and the ones used in "bits" are the ones whose bit
numbers are directly matching the GPIO offset/line numbers of the chip. But I
only used unsigned long, not arrays, so I thought I was limited to offset/line
31 on 32bit arch, and 63 on 64bit arch.
As you suggested, I'm currently having a look to gpiod_get_array_value_complex()
but I must admit I'm currently a little bit lost. I've never thought GPIO
implementation could become so complex for my brain :-)

>> OK
>>
>>>> 3 - Is there some way to request a GPIO already owned by another process as
>>>> input or output, just to get the current level on the input or the level
>>>> driven on output ? This would be much more efficient for real-time
>>>> applications than asking the owner such information.
>>>>
>>>
>>> Ha! Please help me help you. Take a look at the DBus daemon I recently
>>> posted[1]. With the daemon running, the behavior will be exactly what
>>> you expect. You'll be able to get/set values and have the command-line
>>> tool exit while the daemon retains the state.
>>>
>>
>> I was thinking about some specific "watcher" ioctl to do so, not a DBus
>> daemon because this is not welcome in the real-time and embedded world.
>> The only workaround I've found is to directly read the GPIO chip registers
>> but this is bad to do so.
>>
>
> No there isn't, and I can't say I'm a fan of using GPIOs as shared memory,
> though it does seems to be a common use case for those accustomed to accessing
> hardware registers directly.
>

As a workaround, using debugfs in the driver to report the current state of
GPIOs to all processes requiring them is probably cleaner that doing a direct
access to the register. But this is not as clean as a specific "watcher"
ioctl could be.

> I would question whether "much more efficient" is true, as going through all
> the gpiolib machinery, including the device driver, to perform the get could
> even turn out to be slower than some IPC options - such as actual shared
> memory.
>

Yes, you're probably right. "more efficient" was refering to the less you have
layers the more is is supposed to be fast, but there's still some machinery
to go through.

> Cheers,
> Kent.
> .

Thanks a lot,
Gilles
.





[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux