Support for GPIO-driven interrupts


44 posts   Page 1 of 2   1, 2
by Mrkva » Tue Jun 05, 2012 2:35 am
Hey kids!
since official kernel is still missing support for GPIO-driven interrupts (a feature I really *need*), I've decided to wire a quick and dirty one :)
http://dev.mrkva.eu/rpi/linux-gpio-irq.patch - patch for current kernel from https://github.com/raspberrypi/linux.git (commit 94fbbc4e3988075abad0d3b32842b82c590324fc)
http://dev.mrkva.eu/rpi/gpio-irq-demo.c - demo in C using sysfs interface. Usage is simple:
Code: Select all
echo $gpio > /sys/class/gpio/export
echo $trigger > /sys/class/gpio/gpio$gpio/edge
./gpio-irq-demo $gpio

$gpio is GPIO pin number and $trigger can be none (interrupt disabled), rising (trigger interrupt on rising edge of signal) falling (trigger interrupt on falling edge of signal) or both.
Also, please note that there is no guarantee it would work for you or make your RPi explode.
Posts: 5
Joined: Fri Mar 16, 2012 9:25 pm
by jbeale » Wed Jun 06, 2012 4:35 am
Good work, it is really great to see this capability available! -although I can see that I need to do some reading, as the interrupt-driven example code looks very unfamiliar to me (never done any interrupt stuff in Linux).
User avatar
Posts: 1958
Joined: Tue Nov 22, 2011 11:51 pm
by dom » Sat Jun 30, 2012 10:51 am
@Mrkva
Thanks for the patch. It looks okay, and I didn't see any problems after applying it, so I've added it to linux kernel. Could be useful for others.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 3987
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by karl101 » Sat Jun 30, 2012 8:48 pm
Not entirely sure what GPIO-driven interrupts are, I have no C or Kernel programming experience. But will this solve the root permissions problem? eg, Python programs that use the GPIO have to run as root to work. Will I be able to change the group permissions with a udev rule?

Thanks
Karl.
Posts: 61
Joined: Wed Jan 11, 2012 10:09 am
by domesday » Sat Jun 30, 2012 11:18 pm
No, an interrupt means that instead of having to keep polling the GPIO for changes the operating system will be notified when a change occurs.

Think of it like this, if you want to know if someone is at your door, you keep going to the door every 30 seconds to check, this is very inefficient as you don't have much time left to do anything else. Instead you install a door bell so you can happily go about your normal day knowing that when someone comes to the door you will be interrupted by the door bell.
Posts: 258
Joined: Fri Oct 21, 2011 5:53 pm
Location: UK
by pygmy_giant » Sun Jul 01, 2012 12:01 am
Handy - will this work on all Pi linux Operaring Systems such as Puppi which is still in alpha?
Ostendo ignarus addo scientia.
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by karl101 » Sun Jul 01, 2012 10:23 am
domesday wrote:Think of it like this, if you want to know if someone is at your door, you keep going to the door every 30 seconds to check, this is very inefficient as you don't have much time left to do anything else. Instead you install a door bell so you can happily go about your normal day knowing that when someone comes to the door you will be interrupted by the door bell.


That's a very clear explanation, very useful.
Thanks
Posts: 61
Joined: Wed Jan 11, 2012 10:09 am
by selsinork » Sun Jul 01, 2012 1:58 pm
needs this to work properly on bootc's 3.2.2x kernels

Code: Select all
diff --git a/arch/arm/mach-bcm2708/include/mach/gpio.h b/arch/arm/mach-bcm2708/include/mach/gpio.h
index 90a7ba2..a2f8a0f 100644
--- a/arch/arm/mach-bcm2708/include/mach/gpio.h
+++ b/arch/arm/mach-bcm2708/include/mach/gpio.h
@@ -40,6 +40,8 @@ static inline unsigned irq_to_gpio(unsigned irq) {
 static inline unsigned gpio_to_irq(unsigned gpio) {
        return GPIO_IRQ_START+gpio;
 }
+#define gpio_to_irq gpio_to_irq
+
 #endif /* CONFIG_GPIOLIB */
 
 #endif

This is due to gpio_to_irq being provided as a generic function now and we need to override it to prevent a recursive loop where bcm2708_gpio_to_irq calls itself repeatedly untill the system dies
Posts: 151
Joined: Mon Apr 16, 2012 8:31 am
by maddin1234 » Sat Aug 04, 2012 8:49 pm
Hello,
I am sorry, but when I read the gpio-irq-demo,
the code looks like "running to the door every 30 secs"
and not like "being interrupted by the bell".

It can only help detecting a level-change on a pin without
buffering the previous pin levels in my own sourcecode, but I
didn't find any possibility to get a sleeping thread running
without polling sysfs by another thread.

Please correct me, if I didn't understand the code right
and give me an example how to realize it.

Greetings maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm
by giogonza » Sat Aug 11, 2012 1:11 am
Hi, I got a question. Would this interrupt method be reliable at a milisecond level or less?
I need to interface the rPi to an analog to digital converter via SPI, the converter generates a data ready signal (DRDY) to interrupt the CPU each time it has a sample available (in intervals of 1ms in my case, for a sampling rate of 1000Samp/sec). Can I accomplish this task with GPIO driven interrupt proposed here without loosing any sample?
Thanks
Posts: 1
Joined: Sat Aug 11, 2012 1:06 am
by Grumpy Mike » Sat Aug 11, 2012 10:06 am
maddin1234 wrote:Hello,
I am sorry, but when I read the gpio-irq-demo,
the code looks like "running to the door every 30 secs"
and not like "being interrupted by the bell".

Sadly this is what passes for an interrupt in Linux land. Like you I would not call this an interrupt at all, but then I am a real time programmer.

This thread offers some solutions:-
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=44&t=9207
User avatar
Posts: 779
Joined: Sat Sep 10, 2011 7:49 pm
Location: Manchester (England England)
by jojopi » Sat Aug 11, 2012 11:31 am
maddin1234 wrote:I am sorry, but when I read the gpio-irq-demo,
the code looks like "running to the door every 30 secs"
and not like "being interrupted by the bell".
It is not. It is going to sleep until woken up by the doorbell. (There is a timeout facility as well, but you can set that to -1 if you do not want it.)
User avatar
Posts: 1944
Joined: Tue Oct 11, 2011 8:38 pm
by maddin1234 » Sat Aug 11, 2012 1:28 pm
Hi jojopi,
can you explain it to me?

Ok, perhaps MY process is sleeping, but then POLL has to run to the
door and wake me up when someone is there.
I didn't have a look into poll.c, but from the name I guess it is polling.

For CPU usage, I do not see an advantage.
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm
by jojopi » Sat Aug 11, 2012 6:33 pm
maddin1234 wrote:Ok, perhaps MY process is sleeping, but then POLL has to run to the
door and wake me up when someone is there.
I didn't have a look into poll.c, but from the name I guess it is polling.
poll(), and the similar select(), are the standard system calls for checking and/or waiting for one or more files to become ready for I/O.

With a timeout value of zero, poll() simply checks whether each of the files is in the requested state and returns immediately. So you can use it to make your own polling loops. But with a non-zero timeout value, and if none of the requested conditions are already met, poll() puts the current process in an (interruptible) sleep state until some asynchronous event elsewhere on the system changes the state of one of files, or causes the timeout to expire.

Neither the user process nor the kernel is wasting any CPU during the period when it is waiting for the pin to change state.

(I am not an expert on kernel internals, but I believe that when the SoC generates the hardware interrupt, the kernel calls gpio_sysfs_irq(), which calls sysfs_notify_dirent() on the "value" file, which calls wake_up_interruptible() with the list of processes currently waiting for the value to change.)
User avatar
Posts: 1944
Joined: Tue Oct 11, 2011 8:38 pm
by maddin1234 » Sun Aug 19, 2012 7:07 am
Hi,
I read very much the last days and now I think I understand.
(Please correct me, if I am wrong)

The Interrupt is handelt by an interrupt-service-routine, inserted into the bcm2708.c file with the
linux-gpio-irq.patch.

The
gpio-irq-demo.c
has nothing to do with irq-handling, it is the application, that is waiting for the data
from the interrupt-service-routine. And this application is not awoken directly by the interrupt, but by
the virtual filesystem, which is recognizing (by polling) that a file was changed.
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm
by prokrypt » Mon Aug 20, 2012 9:07 pm
It does not poll the file. I believe it polls the interrupt, and then reads the file when it receives an interrupt.
Posts: 3
Joined: Thu Aug 09, 2012 4:15 am
by hummel66 » Thu Oct 04, 2012 3:27 pm
Hello,

does anybody have experiences regarding the maximum frequency of interrupts a Raspberry can handle via the virtual filesystem polling? "Frequency" means an amount of interrupts per second, for example.

Thx
Stefan
Posts: 1
Joined: Thu Oct 04, 2012 3:12 pm
by vicary » Tue Oct 09, 2012 7:50 am
hummel66 wrote:Hello,

does anybody have experiences regarding the maximum frequency of interrupts a Raspberry can handle via the virtual filesystem polling? "Frequency" means an amount of interrupts per second, for example.

Thx
Stefan


+1

Working on benchmarks under node.js modules, would also like to know pure C benchmarks for comparison.
User avatar
Posts: 15
Joined: Tue Jul 17, 2012 4:37 am
Location: Hong Kong
by blackghost » Sat Nov 03, 2012 7:13 pm
Hi
Are there support for interrupts in the latest version of the Raspbian image? If no, how can I add this patch? I have to download the kernel source, and recompile the whole kernel or what? It should be really hard for me, as I don't have any Linux knowledge, so is there a way to download this in a package or get a patched image file perhaps?

Thanks
Posts: 1
Joined: Tue Sep 25, 2012 5:53 pm
by andig2 » Mon Nov 05, 2012 11:35 am
+1 would also like to know what/if GPIO interrupts have made it to kernel
Posts: 24
Joined: Wed Oct 31, 2012 9:34 pm
by gordon@drogon.net » Mon Nov 05, 2012 6:52 pm
andig2 wrote:+1 would also like to know what/if GPIO interrupts have made it to kernel


This patch has been in some quite some time now. It's been supported in wiringPI for a couple of months at least...

-Gordon
--
Gordons projects: https://projects.drogon.net/
User avatar
Posts: 1484
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
by andrum99 » Mon Nov 05, 2012 11:20 pm
I have been looking at what is required to use GPIO-driven interrupts on the Pi and it seems that the usermode interface provided is basically a set of files that change in some way when the interrupt fires. The wiringpi library polls the file looking for a change. Is it possible to use inotify instead?

Thanks

Andrew.
My blog, with lots of Raspberry Pi goodness: andrum99.blogspot.co.uk
Posts: 215
Joined: Fri Jul 20, 2012 2:41 pm
by gordon@drogon.net » Tue Nov 06, 2012 8:30 pm
andrum99 wrote:I have been looking at what is required to use GPIO-driven interrupts on the Pi and it seems that the usermode interface provided is basically a set of files that change in some way when the interrupt fires. The wiringpi library polls the file looking for a change. Is it possible to use inotify instead?

Thanks

Andrew.


Although it uses the poll() system call, it's important to note that it doesn't poll in the traditional manner - although you can change the timeout to make it "poll" if that's what you want.

So it's not a "busy" poll at all, but rather that program thread is stalled and de-schedulled by the kernel until the interrupt happens. ie. it consumes zero cpu resources until the interrupt fires. At that point, the kernel wakes the thread up and it carries on.

To use it, you need to create a separate thread from your main program and have that thread wait for the interrupt. (unless you want your entire program to stll in which case you don't need to do that)

The kernel overhead is rather high though - but it was benchmarked at being able to handle over 10,000 interrupts/sec. If you need more than that then you need to drop into the kernel and write a module or something...

Perhaps the paradigm is hard to see though - it's quite different doing this sort of thing in a multi-user, multi-tasking operating system - which you don't have on microcontrollers. I'm thinking of a plan B...

-Gordon
--
Gordons projects: https://projects.drogon.net/
User avatar
Posts: 1484
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
by vrpi » Fri Nov 09, 2012 3:39 pm
Hi all,

Right now this patch does not work with Xenomai. To make it work, the call to generic_handle_irq should be replaced with ipipe_handle_demuxed_irq ( or ipipe_handle_chained_irq depending on xenomai version ). The function is defined in "linux/ipipe.h" so this header must be included.

I tested with kernel 3.2.21 and Xenomai 2.6.1 and it works.

Hth.
Posts: 2
Joined: Wed Nov 07, 2012 10:29 am
by andrum99 » Sun Nov 11, 2012 8:03 pm
gordon@drogon.net wrote:Although it uses the poll() system call, it's important to note that it doesn't poll in the traditional manner - although you can change the timeout to make it "poll" if that's what you want.

So it's not a "busy" poll at all, but rather that program thread is stalled and de-schedulled by the kernel until the interrupt happens. ie. it consumes zero cpu resources until the interrupt fires. At that point, the kernel wakes the thread up and it carries on.


Thanks - that's useful to know. It wasn't obvious to me, from my reading of some online documentation for the poll syscall I found, that it did not actually poll in the sense I assumed.

Andrew.
My blog, with lots of Raspberry Pi goodness: andrum99.blogspot.co.uk
Posts: 215
Joined: Fri Jul 20, 2012 2:41 pm