Khadas Docs

Amazing Khadas, always amazes you!

User Tools

Site Tools


products:sbc:common:applications:gpio:irq

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
products:sbc:common:applications:gpio:irq [2022/06/29 21:51]
127.0.0.1 external edit
products:sbc:common:applications:gpio:irq [2022/08/07 22:41] (current)
olivia [Introduction]
Line 1: Line 1:
-IRQ+====== GPIO Interrupts ====== 
 + 
 +===== Introduction ===== 
 + 
 +The page leads you to use GPIO interrupts with the GPIO number test program on Khadas SBC. 
 + 
 +<WRAP important > 
 +Here we use ''GPIOH_6'' on VIM3 as an example. 
 +</WRAP> 
 +  
 +===== Hardware Connection ===== 
 + 
 +Connect the physical pins ''PIN20'' and ''PIN15'' by using a DuPont line. 
 + 
 +===== System Configuration ===== 
 + 
 +Get ''GPIOH_6'' number 
 + 
 +Refer to [[/products/sbc/vim4/applications/gpio/40pin-header|40-Pin Header]], the GPIO number you get is ''433''
 + 
 +Export GPIO 
 + 
 +```shell 
 +$ echo 433 | sudo tee /sys/class/gpio/export 
 +``` 
 + 
 +<WRAP info > 
 +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 [[products:sbc:vim4:configurations:device-tree-overlay|Device Tree Overlay]] for more details. 
 +</WRAP> 
 + 
 + 
 +===== Demo Source Code ===== 
 + 
 +Get demo source code 
 + 
 +```c gpio_interrupts.c 
 +// 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 
 + 
 +```shell 
 +$ gcc -o gpio_interrupts gpio_interrupts.c 
 +``` 
 + 
 +===== Demonstrate ===== 
 + 
 +The test code running format is as follows: 
 + 
 +```shell 
 +$ sudo ./gpio_interrupts <edge> [pull] 
 + 
 +``` 
 + 
 +Run test: 
 + 
 +```shell 
 +$ sudo ./gpio_interrupts rising down 
 +
 +GPIO 433 interrupt occurred! 
 +.. 
 +GPIO 433 interrupt occurred! 
 +
 +GPIO 433 interrupt occurred! 
 +
 +GPIO 433 interrupt occurred! 
 +``` 
Last modified: 2022/06/29 21:51 by 127.0.0.1