BeagleBone Black GPIO选择不起作用。

3

我尝试检测GPIO引脚从低电平到高电平的变化,但遇到了问题。根据我所了解的,我应该这样将引脚配置为输入:

# echo in > /sys/class/gpio/gpio51/direction
# echo rising > /sys/class/gpio/gpio51/edge

接下来,我尝试运行一个使用select等待上升沿的C程序。 代码如下(请注意,我注释掉了尝试只读取文件的代码,因为如果您不设置O_NONBLOCK,则读取将被阻止):

#include<stdio.h>                                                                                                                                                                
#include<fcntl.h>                                                                                                                                                                
#include <sys/select.h>                                                                                                                                                          


int main(void) {                                                                                                                                                                 
  int fd = open("/sys/class/gpio/gpio51/value", O_RDONLY & ~O_NONBLOCK);                                                                                                         
  //int fd = open("/sys/class/gpio/gpio51/value", O_RDONLY | O_NONBLOCK);                                                                                                        
  //unsigned char buf[2];                                                                                                                                                        
  //int x = read(fd, &buf, 2);                                                                                                                                                   
  //printf("%d %d: %s\n", fd, x, buf);                                                                                                                                           
  fd_set exceptfds;                                                                                                                                                              
  int    res;                                                                                                                                                                    

  FD_ZERO(&exceptfds);                                                                                                                                                           
  FD_SET(fd, &exceptfds);                                                                                                                                                        
  //printf("waiting for %d: %s\n", exceptfds);                                                                                                                                   
  res = select(fd+1,                                                                                                                                                             
               NULL,               // readfds - not needed                                                                                                                       
               NULL,               // writefds - not needed                                                                                                                      
               &exceptfds,                                                                                                                                                       
               NULL);              // timeout (never)                                                                                                                            

  if (res > 0 && FD_ISSET(fd, &exceptfds)) {                                                                                                                                     
    printf("finished\n");                                                                                                                                                        
  }                                                                                                                                                                              
  return 0;                                                                                                                                                                      
}

无论引脚的状态是高电平还是低电平,程序都会立即退出。有人能看出我做法存在什么问题吗?
PS. 我有一个使用poll()来完成这个任务的Python库,而且Python的工作效果也符合预期。我将引脚拉低,调用Python库,它就会阻塞,然后将引脚拉高,代码继续执行。所以我不认为这是Linux GPIO驱动程序的问题。 https://bitbucket.org/cswank/gadgets/src/590504d4a30b8a83143e06c44b1c32207339c097/gadgets/io/poller.py?at=master
1个回答

4

我已经弄清楚了。在select调用返回之前,您必须从文件描述符中读取。以下是一个可行的示例:

#include<stdio.h>                                                                                                                                                                                                                  
#include<fcntl.h>                                                                                                                                                                                                                  
#include <sys/select.h>                                                                                                                                                                                                            

#define MAX_BUF 64                                                                                                                                                                                                                 

int main(void) {                                                                                                                                                                                                                   
  int len;                                                                                                                                                                                                                         
  char *buf[MAX_BUF];                                                                                                                                                                                                              
  int fd = open("/sys/class/gpio/gpio51/value", O_RDONLY);                                                                                                                                                                         
  fd_set exceptfds;                                                                                                                                                                                                                
  int    res;                                                                                                                                                                                                                      

  FD_ZERO(&exceptfds);                                                                                                                                                                                                             
  FD_SET(fd, &exceptfds);                                                                                                                                                                                                          
  len = read(fd, buf, MAX_BUF);  //won't work without this read.                                                                                                                                                                                                  
  res = select(fd+1,                                                                                                                                                                                                               
               NULL,               // readfds - not needed                                                                                                                                                                         
               NULL,               // writefds - not needed                                                                                                                                                                        
               &exceptfds,                                                                                                                                                                                                         
               NULL);              // timeout (never)                                                                                                                                                                              

  if (res > 0 && FD_ISSET(fd, &exceptfds)) {                                                                                                                                                                                       
    printf("finished\n");                                                                                                                                                                                                          
  }                                                                                                                                                                                                                                
  return 0;                                                                                                                                                                                                                        
}                                                                                                                                                                                                                                  

1
我想知道是否可以使用命令行工具(如cat、tail、head、dd等)以及一些特定的参数来执行此操作。 - Asain Kujovic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接