0
votes

I try to use GPIO interrupt by checking the /sys/class/gpio/gpioN/value.

But the poll() function which checks the interrupt event returns the abnormal value.

First I set the gpioN to proper states in the init.rc

  • write /sys/class/gpio/export "N"
  • write /sys/class/gpio/gpioN/active_low "1"
  • write /sys/class/gpio/gpioN/direction "in"
  • write /sys/class/gpio/gpioN/edge "falling"

And the code checking the interrupt event is like the following.

jint Java_kr_iges_wallpad_gpiotest_MainActivity_GPIORead(JNIEnv *env, jobject obj, jchar port)
{
    int fd, ret;
    struct pollfd fdset[1];
    char buf[32];

    if ((fd = gpio_fd_open(port)) == -1 ){
        LOGE("Read Port open error");
        return -1;
    }

    gpio_poll_fd.fd = fd;
    gpio_poll_fd.events = POLLPRI;
    gpio_poll_fd.revents = 0;

    while (1) {
        ret = poll(&gpio_poll_fd, 1, 3000);
        if (ret > 0) {
            if ((gpio_poll_fd.revents & POLLPRI) == POLLPRI){
                LOGD("GPIO interrupt!");

                ret = 0;
                break;
            } else {
                LOGW("No GPIO interrupt detected, weird.");
            }
        } else if (ret == 0) {
            LOGE("poll call timed out, should not be possible!");
        } else {
            LOGE("poll call failed - %s.", strerror(errno));
            break;
        }
    }

    close(fd);
    return ret;
}


int gpio_fd_open(unsigned int gpio)
{
    int fd, len;
    char buf[MAX_BUF];

    len = snprintf(buf, sizeof(buf), GPIO_PATH "/gpio%d/value", gpio);

    fd = open(buf, O_RDONLY | O_NONBLOCK );
    if (fd < 0) {
        perror("gpio/fd_open");
    }

    return fd;
}

The problem is that gpio_poll_fd.revents of poll() is always POLLPRI( always GPIO is Interrupted).

The /sys/class/gpio/gpioN/value is steadily changed according to GPIO input.

How can I resolve this problem?

Thanks.

1
Are you saying your GPIO pin should not generate an interrupt? Are you sure ? Is it wired up properly ? Have you verified gpio_fd_open() opens the GPIO pin you expect it to open (look in /proc/XXX/fd where XXX is the pid of your running program)? - nos
Hello nos, gpio_fd_open() opens the GPIO pin correctly. I checked the fd in /proc/XXX. Now I expect that POLLPRI is returned when GPIO Pin falling edge. But it is always POLLPRI even though GPIO keeps high. - andy
Note that you're using the legacy GPIO interface. Since linux 4.6, the proper interface is through /dev/gpiochipN. See tools/gpio in the kernel. - Arnout

1 Answers

0
votes

"After poll(2) returns, either lseek(2) to the beginning of the sysfs file and read the new value or close the file and re-open it to read the value."

https://www.kernel.org/doc/Documentation/gpio/sysfs.txt