The page leads you to use GPIO interrupts with the GPIO number test program on Khadas SBC.
Here we use GPIOH_6
on VIM3 as an example.
Connect the physical pins PIN20
and PIN15
by using a DuPont line.
Get GPIOH_6
number
Refer to 40-Pin Header, the GPIO number you get 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 file /boot/env.txt
.
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!