This is an old revision of the document!
This document mainly introduces how to use GPIO interrupts on Khadas SBC. You will know how to use GPIO interrupts with the GPIO number test program.
Use GPIOH_6
on VIM3 as a example.
Connect the physical pins PIN20
and PIN15
using a DuPont line.
Get GPIOH_6
number
Refer 40-Pin Header to get the GPIO number is 433
.
Export GPIO
$ echo 433 | sudo tee /sys/class/gpio/export
Please use gpio readall to check the status of GPIOH_6, if it is not shown as a normal GPIO, you need to remove uart3 from overlays in the /boot/env.txt file.
Check the Device Tree Overlay for more details.
Get demo source code
// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright (c) 2022 Wesion Technology Co., Ltd. * * Author: Yan <yan-wyb@foxmail.com> * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <poll.h> #define SYSFS_GPIO_DIR "/sys/class/gpio" #define MAX_BUF 255 int gpio_export(unsigned int gpio){ int fd, len; char buf[MAX_BUF]; fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY); if (fd < 0) { fprintf(stderr, "Can't export GPIO %d pin: %s\n", gpio, strerror(errno)); return fd; } len = snprintf(buf, sizeof(buf), "%d", gpio); write(fd, buf, len); close(fd); return 0; } int gpio_unexport(unsigned int gpio){ int fd, len; char buf[MAX_BUF]; fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY); if (fd < 0) { fprintf(stderr, "Can't unexport GPIO %d pin: %s\n", gpio, strerror(errno)); return fd; } len = snprintf(buf, sizeof(buf), "%d", gpio); write(fd, buf, len); close(fd); return 0; } int gpio_set_edge(unsigned int gpio, char *edge){ int fd, len; char buf[MAX_BUF]; len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio); fd = open(buf, O_WRONLY); if (fd < 0) { fprintf(stderr, "Can't set GPIO %d pin edge: %s\n", gpio, strerror(errno)); return fd; } write(fd, edge, strlen(edge)+1); close(fd); return 0; } int gpio_set_pull(unsigned int gpio, char *pull){ int fd, len; char buf[MAX_BUF]; len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/pull", gpio); fd = open(buf, O_WRONLY); if (fd < 0) { fprintf(stderr, "Can't set GPIO %d pin pull: %s\n", gpio, strerror(errno)); return fd; } write(fd, pull, strlen(pull)+1); close(fd); return 0; } int main(int argc, char *argv[]) { struct pollfd fdset[2]; int fd, ret, gpio; char buf[MAX_BUF]; if (argc < 3 || argc > 4) { fprintf(stdout, "usage : sudo sysfs_irq_test <gpio> <edge> [pull]\n"); fflush(stdout); return -1; } gpio = atoi(argv[1]); if (gpio_export(gpio)) { fprintf(stdout, "error : export %d\n", gpio); fflush(stdout); return -1; } if (gpio_set_edge(gpio, argv[2])) { fprintf(stdout, "error : edge %s\n", argv[2]); fflush(stdout); return -1; } if (argv[3] && gpio_set_pull(gpio, argv[3])) { fprintf(stdout, "error : pull %s\n", argv[3]); fflush(stdout); return -1; } snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio); fd = open(buf, O_RDWR); if (fd < 0) goto out; while (1) { memset(fdset, 0, sizeof(fdset)); fdset[0].fd = STDIN_FILENO; fdset[0].events = POLLIN; fdset[1].fd = fd; fdset[1].events = POLLPRI; ret = poll(fdset, 2, 3*1000); if (ret < 0) { perror("poll"); break; } fprintf(stderr, "."); if (fdset[1].revents & POLLPRI) { char c; (void)read (fd, &c, 1) ; lseek (fd, 0, SEEK_SET) ; fprintf(stderr, "\nGPIO %d interrupt occurred!\n", gpio); } if (fdset[0].revents & POLLIN) break; fflush(stdout); } close(fd); out: if (gpio_unexport(gpio)) { fprintf(stdout, "error : unexport %d\n", gpio); fflush(stdout); } return 0; }
Compile the source code
$ gcc -o gpio_interrupts gpio_interrupts.c
The test code running format is as follows:
$ sudo ./gpio_interrupts <edge> [pull]
Run test:
$ sudo ./gpio_interrupts rising down
.
GPIO 433 interrupt occurred!
..
GPIO 433 interrupt occurred!
.
GPIO 433 interrupt occurred!
.
GPIO 433 interrupt occurred!