Linux Device Driver Tutorial Part 35 – GPIO Linux Device Driver Basic 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 35 – GPIO Linux Device Driver Basic using Raspberry PI.

In our previous tutorials, we have just used the Laptop or Desktop to learn the Linux Device Drivers. That will be useful for beginners who want to learn the device drivers without hardware. But, many followers of the EmbeTronicX has requested us to provide the Linux Device Driver tutorials using real hardware. So we have come up with the Raspberry Pi.

Many of you know about Raspberry Pi. So I don’t want to waste your time explaining that. We are using the Raspberry PI 4 Model B for our tutorials.

GPIO Linux Device Driver Basic using Raspberry PI

Hardware Required

  • Raspberry Pi
  • Breadboard
  • Resistor
  • LED

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.

Now we are ready to write the GPIO Linux Device Driver. Before we start, we will discuss the GPIO API which is available in the Linux kernel.

Accessing the GPIO in Linux Kernel

If anyone wants to access the GPIO from the Kernel GPIO subsystem, they have to follow the below steps.

  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. Export the GPIO to sysfs (This is optional).
  4. Set the direction of the GPIO
  5. Make the GPIO to High/Low if it is set as an output pin.
  6. Set the debounce-interval and read the state if it is set as an input pin. You enable IRQ also for edge/level triggered.
  7. Then release the GPIO while exiting the driver or once you are done.

The APIs used to do the above steps are given below. Keep reading guys.

GPIO APIs in Linux kernel

Already Kernel GPIO subsystems have provided the APIs to access the GPIOs. We will explain one by one and its uses. Let’s go. You need to include the GPIO header file given below.

#include <linux/gpio.h>

Validate the GPIO

Before using the GPIO, we must check the GPIO that we are planning to use is valid or not. To do that we have to use the below API.

bool gpio_is_valid(int gpio_number);

Where,

gpio_number : GPIO that you are planning to use

It returns false if it is not valid otherwise, it returns true.

This API determines whether the GPIO number is valid or not. Sometimes this call will return false even if you send the valid number. Because that GPIO pin might temporarily unused on a given board.

Request the GPIO

Once you have validated the GPIO, then you can request the GPIO using the below APIs.

int gpio_request(unsigned gpio, const char *label)

where,

gpio : GPIO that you are planning to use.

label :  label used by the kernel for the GPIO in sysfs. You can provide any string that can be seen in /sys/kernel/debug/gpioDo cat /sys/kernel/debug/gpioYou can see the GPIO assigned to the particular GPIO.

It returns 0 in success and a negative number in failure.

Note: GPIOs must be allocated before use.

There are other variants also available. You can use any one of them based on your need.

  • int gpio_request_one(unsigned gpio, unsigned long flags, const char *label); –  Request one GPIO.
  • int gpio_request_array(struct gpio *array, size_t num); – Request multiple GPIOs.

Export the GPIO

For debugging purposes, you can export the GPIO which is allocated using the gpio_request()to the sysfs using the below API.

int gpio_export(unsigned int gpio, bool direction_may_change);

where,

gpio :  GPIO that you want to export.

direction_may_change :  This parameter controls whether user space is allowed to change the direction of the GPIO. true – Can change, false – Can’t change.

Returns zero on success, else an error.

Once you export the GPIO, you can see the GPIO in /sys/class/gpio/*. There you can the GPIO’s value, etc. The example is given below.

Unexport the GPIO

If you have exported the GPIO using the gpio_export()then you can unexport this using the below API.

void gpio_unexport(unsigned int gpio)

Where,

gpio : GPIO that you want to unexport

Set the direction of the GPIO

When you are working on the GPIOs, you have set the GPIO as output or input. The below APIs are used to achieve that.

This API is used to set the GPIO direction as input.

int  gpio_direction_input(unsigned gpio)

Where,

gpio : GPIO that you want to set the direction as input.

Returns zero on success, else an error.

This API is used to set the GPIO direction as output.

int  gpio_direction_output(unsigned gpio, int value)

Where,

gpio : GPIO that you want to set the direction as output.

value : The value of the GPIO once the output direction is effective.

Returns zero on success, else an error.

Change the GPIO value

Once you set the GPIO direction as an output, then you can use the below API to change the GPIO value.

gpio_set_value(unsigned int gpio, int value);

where,

gpio :  GPIO that you want to change the value.

value : value to set to the GPIO. 0 – Low, 1 – High.

Read the GPIO value

You can read the GPIO’s value using the below API.

int  gpio_get_value(unsigned gpio);

where,

gpio :  GPIO that you want to read the value.

It returns the GPIO’s value. 0 or 1.

GPIO Interrupt (IRQ)

This concept will be part of the next tutorial.

Release the GPIO

Once you have done with the GPIO, then you can release the GPIO which you have allocated previously. The below API help in that case.

void gpio_free(unsigned int gpio);

where,

gpio :  GPIO that you want to release.

There are other variants also available. You can use any one of them based on your need.

  • void gpio_free_array(struct gpio *array, size_t num); – Release multiple GPIOs.

Now we have seen the APIs that are available in the GPIO subsystem. Now let’s see the GPIOs available in Raspberry Pi.

GPIO in Raspberry PI

40-pins are there in the Raspberry Pi 4 Model B. You can refer here for the GPIO pinouts and its details.

Example Programming

This is a very basic GPIO tutorial. So I am not going to add all the functionalities in this driver. I will connect the one LED in the GPIO 21. And I will turn ON the LED by writing “1” to the driver. If I write “0”, then the LED will go OFF.

Connection Diagram

GPIO Linux Device Driver Basic using Raspberry PI

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
  • use sudo su and enter the password if required to get the root permission
  • echo 1 > /dev/etx_device [This must turn ON the LED].
  • echo 0 > /dev/etx_device [This must turn OFF the LED].
  • cat /dev/etx_device [Read the GPIO value].

Since we are exporting the GPIO 21 to the sysfs using gpio_export()the below steps also should work.

  • echo 1 > /sys/class/gpio/gpio21/value [This must turn ON the LED].
  • echo 0 > /sys/class/gpio/gpio21/value [This must turn OFF the LED].
  • cat /sys/class/gpio/gpio21/value [Read the GPIO value].

Output Video

Click here if you don’t see the output gif

Raspberry Pi GPIO Linux device driver output

This is a very simple GPIO driver to give a basic idea about GPIO driver. In our next tutorial, we will see how to handle the inputs.

5 2 votes
Article Rating
Subscribe
Notify of
guest

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

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
mehmet
mehmet
September 15, 2020 2:54 AM

Great tutorial, waiting for spi, i2c platform devices 🙂

2
0
Would love your thoughts, please comment.x
()
x
%d bloggers like this: