2017-10-19 9 views
1

Ich versuche, einen GPIO-Wert zu lesen, immer wenn es den Zustand ändert.Abfrage nicht zurück auch dort ist Änderung in GPIO FD

/sys/class/gpio/gpio499/value 

I /sys/class/gpio/gpio499/edge gesetzt haben beide

ich sein werde versuchen, die Wertänderung mit Umfrage Befehl in einem separaten Thread zu überwachen. Hier ist der Code-Schnipsel:

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); 
           } 
         } 

       } 
     } 
} 

Das Problem, das ich bin vor, wenn ich Veranstaltungen wie POLLIN gesetzt, Umfrage kehrt sofort zurück. Dies ist so zu verstehen, weil immer Daten in Wert (0 oder 1) GPIO gelesen werden müssen. Ich habe https://www.kernel.org/doc/Documentation/gpio/sysfs.txt verwiesen und Ereignisse als POLLPRI | festgelegt POLLER. Bei dieser Methode wird die Abfrage jedoch nur nach einer Zeitüberschreitung zurückgegeben. Es kehrt nicht zurück, wenn der Wert des GPIO geändert wird. Gibt es irgendwas, was mir hier fehlt? Ich habe auch /sys/class/gpio/gpio499/edge zu steigen, fallen, aber nichts scheint zu funktionieren.

EDIT: Hier ist die Ausgabe von 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 

Hinweis: I-Wert soll auf 0

+0

Haben Sie sicherstellen, dass der Stift konfiguriert arbeiten wird als Eingabe? ('cat/sys/class/gpio/gpio499/direction' sagt _in_?) – Ctx

+0

Vielleicht die Ausgabe von' grep -r./sys/class/gpio/gpio499' (in Ihrer Frage bearbeitet) kann helfen – Ctx

+1

Mögliches Duplikat von [Wie erkennt man eine PIN-Änderung eines GPIO auf Linux-Board] (https://stackoverflow.com/questions/25962574/how- a-pin-change-of-a-gpio-on-linux-board zu erkennen) – Jackson

Antwort

0

die Funktion von 1 erkennen: poll() funktioniert nicht wie der entsandte Code erwartet.

Vorschlag: 1) Lesen Sie die Datei, um den aktuellen Eingabewert zu erhalten. 2) eine Spinschleife ausführen, um den Wert zu lesen, bis der Wert ändert sich ähnlich:

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; 
    } 
} 

Diese Schleife mehr CPU-Zyklen tut brennen, sollte aber

Verwandte Themen