1

每当 Beaglebone Black 的一个引脚出现上升沿时,我想触发一个事件。问题是,即使我没有将该引脚连接到任何东西,输出只是继续打印,发生中断,发生中断。我在 stackoverflow 上遇到了 Beaglebone 中的问题中断, 并尝试按照步骤操作。有一个实现该功能的程序的链接。我阅读了 poll() 并在程序中做了一些细微的改动,因为我只想监控一个引脚。更改后的代码是:

int main(int argc, char **argv, char **envp)
{
struct pollfd fdset[1];  // fdset[2] changed to fdset[1] since I will monitor just 1 pin
int nfds = 1;            // nfds changed from 2 to 1
int gpio_fd, timeout, rc;
char *buf[MAX_BUF];
unsigned int gpio;
int len;



if (argc < 2) {
    printf("Usage: gpio-int <gpio-pin>\n\n");
    printf("Waits for a change in the GPIO pin voltage level or input on stdin\n");
    exit(-1);
}

gpio = atoi(argv[1]);

gpio_export(gpio);
gpio_set_dir(gpio, 0);
gpio_set_edge(gpio, "rising");
gpio_fd = gpio_fd_open(gpio);

timeout = POLL_TIMEOUT;

while (1) {
    memset((void*)fdset, 0, sizeof(fdset));

    fdset[0].fd = gpio_fd;                 // This is the pin to be monitored
    fdset[0].events = POLLIN;

    //fdset[1].fd = gpio_fd;               // commented since I do not need this
    //fdset[1].events = POLLPRI;

    rc = poll(fdset, nfds, timeout);      

    if (rc < 0) {
        printf("\npoll() failed!\n");
        return -1;
    }

    if (rc == 0) {
        printf(".");
    }

    if (fdset[0].revents & POLLIN) {
        len = read(fdset[0].fd, buf, MAX_BUF);
        printf("\npoll() GPIO %d interrupt occurred\n", gpio);
    }

            // ****Commented block****
    //if (fdset[0].revents & POLLIN) {
    //  (void)read(fdset[0].fd, buf, 1);
    //  printf("\npoll() stdin read 0x%2.2X\n", (unsigned int) buf[0]);
    //}

    fflush(stdout);
}

gpio_fd_close(gpio_fd);
return 0;
}

在 Beaglebone black 上运行 Angstrom。

4

2 回答 2

3

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

如果引脚可以配置为产生中断的中断并且它已被配置为产生中断(参见“边缘”的描述),您可以对该文件进行 poll(2),并且 poll(2) 将在中断发生时返回触发。如果使用 poll(2),请设置事件 POLLPRI 和 POLLERR。如果使用 select(2),请在 exceptfds 中设置文件描述符。在 poll(2) 返回后,lseek(2) 到 sysfs 文件的开头并读取新值或关闭文件并重新打开以读取值。

您尚未设置事件 POLLPRI 和 POLLERR。

struct pollfd fdset[1];
memset((void*)fdset, 0, sizeof(fdset));
fdset[0].fd = fd;
fdset[0].events = POLLPRI | POLLERR;
...
poll()
...
lseek(fdset[0].fd, 0, SEEK_SET);
const ssize_t rc = read(fdset[0].fd, buf, MAX_BUF);

以上适用于使用 linux 3.8.13-bone47 运行 Debian 的 BeagleBone Black Rev. C。

于 2014-08-17T10:10:12.930 回答
1

由于您“没有将该引脚连接到任何东西”,如果它没有在内部连接为低电平或高电平,那么它只是一个浮动输入,这可能会导致您看到明显的中断。

于 2014-02-28T21:00:56.510 回答