How can I get edge events via GPIO on Linux without a busy-loop?

Tom Mekken picture Tom Mekken · Dec 9, 2011 · Viewed 8.5k times · Source

I'm working an a system with embedded Linux (Kernel 2.6.31).

It is a AT91SAM9G20 chip inside, and some of the Pins are forwarded to the outside.

Now I want to use them as GPIO Inputs.

I read the gpio.txt documentation about using the GPIOs via filesystem, and that works very well 'til here. I connected some switches to the gpio-pins and I can see the result in /sys/class/gpio/gpioX/value. But now I'd like to react on a change without busy-waiting in a loop. (i.e echo "Switch1 was pressed").

I guess I need interrupts here, but I couldn't find out how to use them without writing my own kernel driver. I'm relatively new to Linux and C (I normally program in Java), so I'd like to handle the Interrupts via sysfs too. But my problem is, that there is no "edge"-file in my GPIO directory (I guess because this is only since Kernel version 2.6.33+). Is that right? Instead of "edge" I've got a uevent file in there, which is not described in gpio.txt.

In the gpio.txt documentation there was a Standard Kernel Driver mentioned: "gpio_keys". Is it possible to use this for my problem?

I guess it would be better to work with this driver than allowing a userspace program to manipulate kernel tasks. I found a lot of codesnippets for writing my own driver, but I wasn't even able to find out which of the 600 gpio.h files to include, and how to refer to the library (cross compiler couldn't find the gpio.h file).

Sorry for newbie questions, I hope you could give me some advices.

Thanks in advance

Answer

Thomas Petazzoni picture Thomas Petazzoni · Dec 9, 2011

See https://www.ridgerun.com/developer/wiki/index.php/Gpio-int-test.c for an example on how to do that. Basically, the thing you're missing is the usage of the select or poll system calls.