2015-07-21 3 views
1

Я пытаюсь получить прерывания на основе GPIO, работающие на GPIO BeagleBone, используя функцию Poll(). Ниже приведен мой код, но в целом:BeagleBone Black GPIO Interrupt with Poll()

Хотя у меня есть контакт, подключенный к земле, ничего не происходит (как и ожидалось).

Когда я подключаю штырь к высокому, генерируется прерывание. Однако он никогда не очищается или не восстанавливается очень быстро. Я внедрил счет, который должен быть увеличен, когда он пойдет высоко, и в течение нескольких секунд счетчик превысил 10 000. Я что-то пропустил в своей настройке? Проблема, вероятно, в моей функции main(), но я включил другие функции для полноты.

Спасибо за любую помощь,

Чарльз

#define SYSFS_GPIO_DIR "/sys/class/gpio" 
#define MAX_BUF 64 

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

    fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY); 
    if (fd < 0) { 
     perror("gpio/export"); 
     return fd; 
    } 

    len = snprintf(buf, sizeof(buf), "%d", gpio); 
    write(fd, buf, len); 
    close(fd); 

    return 0; 
} 

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

    len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", gpio); 

    fd = open(buf, O_WRONLY); 
    if (fd < 0) { 
     perror("gpio/direction"); 
     return fd; 
    } 

    if (direction) 
     write(fd, "out", 4); 
    else 
     write(fd, "in", 3); 

    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) { 
     perror("gpio/set-edge"); 
     return fd; 
    } 

    write(fd, edge, strlen(edge) + 1); 
    close(fd); 
    return 0; 
} 

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

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

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

int gpio_fd_close(int fd) 
{ 
    return close(fd); 
} 

int main() 
{ 
    struct pollfd fdset; 
    int nfds = 1; 
    int gpio_fd, timeout, rc; 
    char *buf[MAX_BUF]; 
    unsigned int gpio; 
    int len; 
    char* c; 


    gpio = 26; 

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

    timeout = 1; 

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

     fdset.fd = gpio_fd; 
     fdset.events = POLLPRI | POLLERR; 

     len = read(fdset.fd, c, 1); 

     rc = poll(&fdset, nfds, timeout); 

     //printf("POLLPRI is %02x, POLLERR is %02x\r\n", POLLPRI, POLLERR); 

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

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

     if (fdset.revents & POLLPRI) { 
      if (len==-1) 
      { 
       printf("Hex of revents is %02x, return code is %02x\r\n", fdset.revents, rc); 
      } 
      len = read(fdset.fd, buf, MAX_BUF); 
     } 

     if (fdset.revents & POLLERR) 
     { 
      printf("errno: %d", errno); 
     } 
    } 

    gpio_fd_close(gpio_fd); 
    return 0; 
} 
+0

Я не читал ваш код, но если вы «подключаетесь» механическим переключателем или подобным (разомкнутый провод), вы должны отменить (просто выполните поиск термина). – Olaf

ответ

0

Я переустановил образ Debian на BeagleBone Блэка, и она работает, как ожидалось в настоящее время. Я не уверен, почему он не работал раньше, но похоже, что это проблема ОС.

Смежные вопросы