2017-10-19 150 views
1

我試圖在每次更改狀態時都讀取一個GPIO值。即使GPIO發生變化,輪詢也不會返回FD

/sys/class/gpio/gpio499/value 

我已經設置/sys/class/gpio/gpio499/edge

我試圖監視一個單獨的線程中使用調查命令值的變化。以下是代碼片段:

void PIN_gpio_poll(size_t gpio)  //GPIO 499 
{ 
     char path[30]; 
     char cValue; 
     int fd; 
     int ret_poll; 
     int ret_read; 
     struct pollfd pollfd; 
     int i; 

     pollfd.events = POLLPRI | POLLERR; /* look for GPIO status change. */ 


     snprintf(path, 30, PHDRIVER_LINUX_CFG_DIR "/gpio%u/value", gpio); 
     fd = open(path, O_RDONLY); 
     if (fd == -1) 
     { 
       printf("Gpio_poll _ERROR\r\n"); 
     } 

     pollfd.fd = fd; 

     ret_read = read(pollfd.fd, &cValue, 1); // Dummy Read to clear 

     while (1) 
     { 
       lseek(fd, 0, SEEK_SET); 
       ret_read = read(fd, &cValue, 1); 
       printf("Value=%c, RET READ=%d\n",cValue,ret_read); 
//    ret_poll = poll(&pollfd, 1, -1); 
       ret_poll = poll(&pollfd, 1, 10000); //10sec timeout 

       printf("******REVENTS=%x\n",pollfd.revents); 
       if(ret_poll == -1) 
       { 
         printf("Gpio_poll poll failed\r\n"); 
         close(fd); 
       }else{ 
//      if (pollfd.revents & POLLPRI) 
         { 
           lseek(fd, 0, SEEK_SET); 
           ret_read = read(pollfd.fd, &cValue, 1); 
           if(ret_read > 0) 
           { 
            printf("Cvalue = %c\n",cValue); 
           } 
         } 

       } 
     } 
} 

我現在面臨的問題是,如果我設置事件POLLIN,調查立即返回。這是可以理解的,因爲總是有數據需要在的值(0或1)GPIO中讀取。我提到https://www.kernel.org/doc/Documentation/gpio/sysfs.txt並將事件設置爲POLLPRI | POLLERR。但是在這種方法中,輪詢僅在超時後才返回。當GPIO的值改變時它不會返回。有什麼我錯過了這裏的訣竅?我也設置/sys/class/gpio/gpio499/edge上升,下降,但似乎沒有任何工作。

編輯: 這裏是grep -r . /sys/class/gpio/gpio499

/sys/class/gpio/gpio499/edge:both 
/sys/class/gpio/gpio499/power/control:auto 
/sys/class/gpio/gpio499/power/runtime_active_time:0 
grep: /sys/class/gpio/gpio499/power/autosuspend_delay_ms: Input/output error 
/sys/class/gpio/gpio499/power/runtime_status:unsupported 
/sys/class/gpio/gpio499/power/runtime_suspended_time:0 
/sys/class/gpio/gpio499/value:1 
/sys/class/gpio/gpio499/active_low:0 
/sys/class/gpio/gpio499/direction:in 

注輸出:我想檢測從1值爲0

+0

你確定,該引腳配置作爲輸入? ('cat/sys/class/gpio/gpio499/direction'說_in_?) – Ctx

+0

也許輸出'grep -r。/sys/class/gpio/gpio499'(編輯到你的問題)可以幫助 – Ctx

+1

[如何檢測Linux板上GPIO引腳變化]可能的重複(https://stackoverflow.com/questions/25962574/how-以檢測一個gpio-on-linux-board上的引腳變化) – Jackson

回答

0

功能:poll()的發佈代碼期待不起作用。

建議:1)讀取文件獲取當前輸入值。 2)執行自旋循環,讀取值,直到值的變化,類似於:

readbytes = read(fd, &cValue, 1); 
while(readbytes > 0) 
{ 
    if((off_t)-1 == lseek(fd, 0, SEEK_SET)) 
    { // then lseek failed 
     perror("lseek failed"); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, lseek successful 

    readbytes = read(fd, &new_cValue, 1); 
    if(0 >= readbytes) 
    { 
     perror("read failed"); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, read successful 

    if(cValue != new_cValue) 
    { // then state changed 
     cValue = new_cValue; 
     break; 
    } 
} 

這個循環不消耗更多的CPU週期,但應該工作

相關問題