Re: GPIO inputs on Pis?

From: Karl Denninger <karl_at_denninger.net>
Date: Sat, 28 Jan 2023 14:58:40 UTC
On 1/25/2023 23:04, Dr. Rolf Jansen wrote:
>> Am 25.01.2023 um 13:45 schrieb Karl Denninger<karl@denninger.net>:
>>
>> On 1/24/2023 14:15, Dr. Rolf Jansen wrote:
>>> Yes, and for this reason, this GPIO event code which was developed by Christian Krämer in the course of the GSoC-2018 and has been submitted in 2020 by Ian Lepore to the freebsd tree is perfect.
>>>
>>> Ian tested it with a 10 MHz sqaure wave on an imx6 (ARMv7, 1GHz) and got an event every 10 µs. That means the max. speed without event losses would be 100 kHz. I did not do exact measurements, however, my impression is that my RPi4B can do it a tad faster than my BeagleBone Black. With the RPi4, I needed to improve the debouncing of the encoder and the buttons, because it saw hundreds of bounces which the BBB didn’t. However, it may also be, that the internal GPIO circuits of the BBB have a different damping characteristic.
>>>
>>> Anyway for my applications, 100 kHz way faster than what I need.
>>>
>>> On my GitHub repository I placed another example on using the GPIO events for the RPi:
>>>
>>> https://github.com/cyclaero/shutdd
>>>
>>> See also the respective thread on this mailing list:
>>>
>>> https://lists.freebsd.org/archives/freebsd-arm/2022-July/001576.html
>> So..... just to see  if I'm understanding this correctly (pretty sure I am having read through the test code).
>>
>> Presume I have "X" pins configured as inputs and "Y" configured as outputs.  I use the ioctl calls to set the outputs (which works just fine) and can read current input state (which also works.)
>>
>> If I set on the same descriptor (not on the specific pins; it applies to all input pins on that descriptor as it appears there's no pin-specific setting in the configuration flags to enable this on a pin-by-pin basis) the event report config type I want I can then select() on the descriptor with the usual timeouts (or zero for a poll) and get a "ready" (much as one would for any other sort of I/O) and, if I do get a "ready" return on the descriptor a read() on that descriptor will return zero or more structures of the type I said I configured, each of which describes either an individual state change on one of configured input pins that is set up for individual event reporting OR a structure of the summary of changes for a given pin.
>>
> My understanding of what you wrote above sounds correct. However, I don’t use select(), since I am very comfortable with calling a blocking read() from a loop in a pthread. The advantage with this is, that there is almost no time gap in the user land between reading of the events. Below comes an example

It does indeed work "as-expected" from my testing; this is a welcome 
addition that I did not realize was there (when I originally started 
working with this stuff it wasn't in the kernel, materially before the 
ARM code was considered Tier 1.)

BTW one warning which might be worthy of at least a note in the man page 
-- if you enable reporting but do not assign any pins to have interrupts 
enabled you will get a "ready for read" immediately on a poll or select, 
but an attempt to read the descriptor comes back with ENXIO.

IMHO a select() or poll() should not return a ready state for reads 
unless it really is ready to be read (it would be ok to return a "ready 
on error/exception" of course; I haven't checked that.)  The man page is 
too sparse to know if this is intended behavior or a bug against which 
perhaps I should file a PR.

I also generated a panic in the provided test code on the Pi3 by setting 
nonblocking and using select.  Unfortunately I do not have a crash dump 
from it as it occurred on an embedded test board.

Thanks.

-- 
Karl Denninger
karl@denninger.net
/The Market Ticker/
/[S/MIME encrypted email preferred]/