Linux Device Driver Tutorial Part 36 – GPIO Linux Device Driver using Raspberry PI

This is the Series on Linux Device Driver. The aim of this series is to provide easy and practical examples that anyone can understand. This is the Linux Device Driver Tutorial Part 36 – GPIO Linux Device Driver using Raspberry PI.

In our previous tutorial, we have just used the GPIO pin as an output and we made it high and low. In this tutorial, we will see how to handle the input from GPIO.

We are using the Raspberry PI 4 Model B for this demonstration.

GPIO Linux Device Driver

Prerequisites

Hardware Required

  • Raspberry Pi
  • Breadboard
  • Resistor
  • LED
  • Push-button (In our tutorial, we have used a vibration sensor as an input device)

Bring up Raspberry PI

  1. Install Raspberry Pi OS (32-bit) with desktop in the SD card.
  2. Then install the kernel header using sudo apt install raspberrypi-kernel-headers

For your information, In my Raspberry PI 4 board, kernel 5.4.51-v7l+ is installed.

Accessing the input GPIO in Linux Kernel

  1. Verify the GPIO is valid or not.
  2. If it is valid, then you can request the GPIO form the Kernel GPIO subsystem.
  3. Set the direction of the GPIO as an input
  4. Set the debounce-interval
  5. Read the GPIO.
  6. You enable IRQ also for edge/level triggered if you need it.
  7. Then release the GPIO while exiting the driver or once you are done.

GPIO APIs in Linux kernel

We have seen almost all the APIs in our last tutorial. So, Please have a look at there. Here we will see the APIs that we have missed in that last tutorial.

Set the debounce-interval

The below API is used for sets debounce time for a GPIO. Right now raspberry pi is not supporting that. That’s why we have commented on that line in our source code. Instead, we used some software hack to eliminates multiple time IRQ being called for a single rising edge transition. You can remove the software hack and uncomment that gpio_set_debounce() if your microcontroller supports this.

int gpiod_set_debounce(unsigned gpio, unsigned debounce);

where,

gpio :  GPIO that you want to set the debounce value.

debounce : Delay of the debounce.

It returns 0 on success. otherwise, <0.

Get the IRQ number for the GPIO

Using the below API, you can get the IRQ number for the specific GPIO.

int gpio_to_irq(unsigned gpio);

where,

gpio :  GPIO that you want to get the IRQ number.

Request the IRQ

Here where you need to register the GPIO IRQ number and its handler to the Linux Interrupts with the proper interrupt flags. You can find the details regarding requesting the GPIO here. Please note that you have to free the IRQ once you are done with the interrupt.

Interrupt Flags

While registering the GPIO interrupt using request_irq() you can use any one of the flags based on your need.

So we are all set. Let’s jump into the programming.

Example Programming

In this example, I have just taken the 2 GPIOs. One is for the input and one is for the output.

  • GPIO 21 – OUTPUT
  • GPIO 25 – INPUT

LED has been connected to the OUTPUT pin (GPIO 21) and the Vibration sensor has been connected to the INPUT pin (GPIO 25). You can connect the push-button also into the INPUT pin.

So the concept is whenever the vibration is detected, it will toggle the LED. Just simple right. Let’s write the code.

Connection Diagram

Driver Source Code

[Get the source code from the GitHub]

Makefile

Testing the Device Driver

  • Build the driver by using Makefile (sudo make)
  • Load the driver using sudo insmod driver.ko
  • Just press the button or vibrate the vibration sensor.
  • That output LED should be toggled.

Output Video

Click here if you don’t see the output gif

GPIO Linux Device Driver using Raspberry Pi

In our next tutorial, we will see the I2C and its subsystem in the Linux Device Driver.

5 3 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
%d bloggers like this: