Embedded system interrupt/hardware handling for Linux
On my AT91SAM9RL-EK ARM board, running Linux 2.6.30 buildroot, I have the following.
cat /proc/interrupts
CPU0
1: 6475 AIC at91_tick, rtc0, ttyS0
10: 11 AIC mmc0
13: 4 AIC atmel_spi.0
18: 23533 AIC tc_clkevt
20: 0 AIC atmel_tsadcc
22: 0 AIC atmel_usba_udc
23: 0 AIC atmel_lcdfb
24: 0 AIC AC97C
40: 1 GPIO atmel_usba_udc
47: 0 GPIO mmc0
64: 6 GPIO Right Click
65: 10 GPIO Left Click
Right and left are the buttons on my board. Now I want to modify the interrupt handlers of the buttons (e.g. they give me an output when clicked).
Where can I find the interrupt handler or driver (or their source files) for the button?
Or can I write my own drivers and register them for the buttons (when I’m in user space) and how?
Here is some data on PIO in the board guide
IO... Per.... Application Usage............................................ Pow. by
PB0 TXD3 USER’S PUSH BUTTON 1 PB0 as LEFT CLICK VDDIOP
PB1 RXD3 USER’S PUSH BUTTON 2 PB1 as RIGHT CLICK VDDIOP
Solution
I
don’t have specific answers for your board, but I can give you some guidance based on the information you need.
The easiest way to solve your problem is to drop the “interrupt handler” requirement and simply poll the GPIO line. As long as you are the root user, you can do this from user space. Many development environments provide a kernel module to do this for you, exposing the results as entries in /dev
or /proc
.
If you want to handle interrupts, you need to write a Linux device driver. The best place to start is the great Linux device driver book, available for download at http://lwn.net/Kernel/LDD3/.
GPIO drivers are very simple and consist primarily of code that calls register_irq()
and your user-space interface (interface). The user space interface code will be much larger than the rest of the code and will also give you the most headaches.