1. Purpose[edit | edit source]
This article shows two ways to control a GPIO in userspace:
- using libgpiod
- by writing an application
2. GPIO control through libgpiod[edit | edit source]
libgpiod provides a C library and tools for interacting with the linux GPIO character device (gpiod stands for GPIO device). See the libgpiod repository[1] for further explanation.
- gpiodetect
- List all gpiochips present on the system
- Usage:
gpiodetect gpiochip0 [GPIOA] (16 lines) ... gpiochip9 [GPIOZ] (8 lines)
- gpioinfo
- list all lines of specified gpiochips, their names, consumers, and their settings
- Usage:
gpioinfo gpiochip0 - 16 lines: line 0: "PA0" unused input active-high line 1: "PA1" unused input active-high ...
or
gpioinfo -c gpiochip0 --> to only print gpiochip0 lines
- gpioget
- Read the values of the specified GPIO lines (not valid if the line is already requested). The line will be then configured as input.
gpioget -c gpiochip0 13 --> to get value of GPIO PA5 "13"=inactive --> means the line is driven low
- gpioset
- Set the values of the specified GPIO lines, potentially keeping the lines exported, and wait until timeout, user input or signal (not valid if the line is already requested).
gpioset -c gpiochip0 14=0 --> get GPIO PA14 and set it low (green led on) Ctrl + C gpioset -c gpiochip0 14=1 --> get GPIO PA14 and set it high (green led off) Ctrl + C gpioset -t 500ms -c gpiochip0 14=active --> get GPIO PA14 and toogle it every 500ms (green led blink) Ctrl + C
3. GPIO control through your own application[edit | edit source]
3.1. Purpose[edit | edit source]
This application toggles GPIO PA14 (GPIO bank A, line 14). On STM32MP15_Evaluation_boards or STM32MP15_Discovery_kits GPIO PA14 is connected to the green LED.
This application must be cross compiled with same toolchain as the Kernel.
3.2. Code[edit | edit source]
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/gpio.h>
int main(int argc, char **argv)
{
struct gpiohandle_request req;
struct gpiohandle_data data;
char chrdev_name[20];
int fd, ret;
strcpy(chrdev_name, "/dev/gpiochip0");
/* Open device: gpiochip0 for GPIO bank A */
fd = open(chrdev_name, 0);
if (fd == -1) {
ret = -errno;
fprintf(stderr, "Failed to open %s\n", chrdev_name);
return ret;
}
/* request GPIO line: GPIO_A_14 */
req.lineoffsets[0] = 14;
req.flags = GPIOHANDLE_REQUEST_OUTPUT;
memcpy(req.default_values, &data, sizeof(req.default_values));
strcpy(req.consumer_label, "led_gpio_a_14");
req.lines = 1;
ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
if (ret == -1) {
ret = -errno;
fprintf(stderr, "Failed to issue GET LINEHANDLE IOCTL (%d)\n",
ret);
}
if (close(fd) == -1)
perror("Failed to close GPIO character device file");
/* Start led blinking */
while(1) {
data.values[0] = !data.values[0];
ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
if (ret == -1) {
ret = -errno;
fprintf(stderr, "Failed to issue %s (%d)\n",
"GPIOHANDLE_SET_LINE_VALUES_IOCTL", ret);
}
sleep(1);
}
/* release line */
ret = close(req.fd);
if (ret == -1) {
perror("Failed to close GPIO LINEHANDLE device file");
ret = -errno;
}
return ret;
}
3.3. Build application[edit | edit source]
See Adding_Linux_user_space_applications to build this application.
4. References[edit | edit source]