Pages

Saturday, May 31, 2014

Using Rapsberry Pi's GPIO as an interrupt source

Normally its quite difficult to implement device drivers that handles interrupts in the Linux desktop since there are only a few hardware that can generate interrupt (parallel port, etc.). The raspberry pi presents a unique learning opportunity for me to experiment writing device drivers that implements interrupt handlers by assigning one of the GPIO pins as an interrupt source. Before going into details of my experiments, we first need to understand how the GPIO in the raspberry pi are configured, and how to handle kernel interrupts in general.

The GPIO (general purpose input/output) are generally user configurable input/output pins in an embedded system used to communicate with external devices. In linux control of these GPIO input/output pins are done by the  soc, and in the case of the raspberry pi, they are connected to the bcm2835/bcm2708 soc. To control these gpio pins, let us first examine how we can do this in user space.

1) To enable the GPIO pins to be used, we need to export this pin in the kernel. If you browse to /sys/class/gpio on your raspberry pi, you will notice the kernel attributes defined:


pi@raspberrypi /sys/class/gpio $ ls -lrt
total 0
-rwxrwx--- 1 root gpio 4096 Jan  1  1970 unexport
lrwxrwxrwx 1 root gpio    0 Jan  1  1970 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
-rwxrwx--- 1 root gpio 4096 Jan  1  1970 export
pi@raspberrypi /sys/class/gpio $

Notice the presence of the export and unexport kernel attributes.

2) For this experiment, we need to configure GPIO pin #23, from the raspberry pi as an input pin. Attached is the pinout for the raspberry pi.



You can connect this pin to a push button switch with a pull-up resistor from the circuit shown below:


3) Since we are going to be needing GPIO23 as input, we first need to export this pin via the command:

pi@raspberrypi /sys/class/gpio $ echo 23 > ./export
pi@raspberrypi /sys/class/gpio $ ls
export  gpio23  gpiochip0  unexport
pi@raspberrypi /sys/class/gpio $

Once we export GPIO23 above, the following ls command displays a new directory link to gpio23.

4) We now need to set the direction of this GPIO23 pin as input. To do that navigate into the newly create directory and modify the direction using the command:

pi@raspberrypi /sys/class/gpio $ cd gpio23
pi@raspberrypi /sys/class/gpio/gpio23 $ ls
active_low  direction  edge  power  subsystem  uevent  value
pi@raspberrypi /sys/class/gpio/gpio23 $ echo "in" > ./direction
pi@raspberrypi /sys/class/gpio/gpio23 $

The last command assigns GPIO23 as an input pin.

5) To test if this setup is working, examine the value of this pin by the following:

pi@raspberrypi /sys/class/gpio/gpio23 $ cat value
1
pi@raspberrypi /sys/class/gpio/gpio23 $

Press the button and issue the command below should show that the button was pressed.

pi@raspberrypi /sys/class/gpio/gpio23 $ cat value
0
pi@raspberrypi /sys/class/gpio/gpio23 $

Ok, so now that we have the setup working, we can now use GPIO23 as our interrupt source for our device driver.. 

Will discuss this in my next post.

No comments: