Monday, February 14, 2011

GPIO Interrupt in Linux

[1] http://bec-systems.com/site/281/how-to-implement-an-interrupt-driven-gpio-input-in-linux
[2] Linux Device Drivers 3rd Edition.
[3] http://blackfin.uclinux.org/gf/project/uclinux-dist/forum/?_forum_action=ForumMessageBrowse&thread_id=23417&action=ForumBrowse
[4] http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:simple-gpio
[5] http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:gpio-sysfs
[6] http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:interrupts#gpio_interrupt_processing

[7] http://osdir.com/ml/android-platform/2010-01/msg00294.html
[8] http://linux.derkeiler.com/Mailing-Lists/Kernel/2009-06/msg04562.html Proposed PATCH for Gpiolib.c/h


irqs.h (x:\lpc3250\ltib-qs\rpm\BUILD\linux-2.6.34\arch\arm\mach-lpc32xx\include\mach)
irq.c (x:\lpc3250\ltib-qs\rpm\BUILD\linux-2.6.34\arch\arm\mach-lpc32xx)
phy3250.c (x:\lpc3250\ltib-qs\rpm\BUILD\linux-2.6.34\arch\arm\mach-lpc32xx) line202 static struct amba_device lpc32xx_ssp0_device

gpiolib.c (x:\lpc3250\ltib-qs\rpm\BUILD\linux-2.6.34\arch\arm\mach-lpc32xx)line 351
static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
{
.chip = {
.label = "gpio_p0",
.direction_input = lpc32xx_gpio_dir_input_p012,
.get = lpc32xx_gpio_get_value_p012,
.direction_output = lpc32xx_gpio_dir_output_p012,
.set = lpc32xx_gpio_set_value_p012,
.request = lpc32xx_gpio_request,
.base = LPC32XX_GPIO_P0_GRP,
.ngpio = LPC32XX_GPIO_P0_MAX,
.names = gpio_p0_names,
.can_sleep = 0,
},
.gpio_grp = &gpio_grp_regs_p0,
},


you cannot write an IRQ handler in userspace, it needs to be in kernel space.

What you will probably end up with is a loadable kernel module containing your interrupt handler and a pseudo-file interface to the variables it manipulates. The interrupt handler executes in its own context. The pseudo-file interface will execute in the kernel context, so be careful to protect the data it shares with the interrupt handler using the appropriate semaphores. You will use file operations at the pseudo-file as a bridge from your user-space program to the kernel space variables manipulated by the interrupt handler.[3]

You will find out when you get into the literature that pseudo-files are not real files and don't have the overhead of actually writing stuff in persistent store. They are ways of using read(), write() and ioctl() functions on file handles from user space to invoke functionality in the kernel. From your application you open a file handle to your pseudo-file and when you call these functions on it code you have added to the kernel springs to life. There is a framework that takes care of the transition from user- to kernel-space. Inside the kernel, your functions can share variables with your interrupt service routine.

This is all standard Linux stuff and you may find out more from general Linux forums (in addition to the right books). [3]



[root@GsnCommsModule user]# cat /proc/interrupts
CPU0
9: 44 - serial
16: 4760671 - LPC32XX Timer Tick
20: 1018101 - pl022
21: 0 - pl022
28: 103638 - DMA
29: 901999 - eth0
50: 0 - pnx-i2c
51: 0 - pnx-i2c
52: 0 - rtc-lpc32xx
59: 216 - ohci_hcd:usb1
63: 45 - pnx-i2c
Err: 0

No comments: