2016-07-29 33 views
0

Ich fange gerade an, für Linux zu programmieren und jetzt möchte ich ein Ereignis auslösen, wenn die externe Taste, die an Beaglebone angeschlossen ist, gedrückt wird. Here Ich habe eine schöne Lösung auf der Basis von Glib gefunden und versucht, sie zu implementieren. Aber leider wird das Ereignis nur einmal am Anfang ausgelöst und dann egal wie oft ich den Knopf drücke reagiert es nicht.GIOCondition G_IO_PRI zum Drücken der Taste auf Beaglebone ist nicht zufrieden

Hier ist der Code genau aus dem Tutorial genommen:

#include<iostream> 
#include<unistd.h> 
#include<fstream> 
#include<stdlib.h> 
#include<sys/types.h> 
#include<sys/stat.h> 
#include<fcntl.h> 
#include<glib-2.0/glib.h> 

using namespace std; 

static gboolean onButtonEvent(GIOChannel *channel, GIOCondition condition, gpointer user_data) 
{ 
    GError *error = 0; 
    gsize bytes_read = 0; 
    const int buf_sz = 1024; 
    gchar buf[buf_sz] = {}; 
    g_io_channel_seek_position(channel, 0, G_SEEK_SET, 0); 
    GIOStatus rc = g_io_channel_read_chars(channel, 
              buf,buf_sz - 1, 
              &bytes_read, 
              &error); 
    cerr << "rc:" << rc << " data:" << buf << endl; 
    return 1; 
} 

int main(int argc, char** argv) 
{ 
    GMainLoop* loop = g_main_loop_new(0, 0); 

    int fd = open("/sys/class/gpio/gpio49/value", O_RDONLY | O_NONBLOCK); 
    GIOChannel* channel = g_io_channel_unix_new(fd); 
    GIOCondition cond = GIOCondition(G_IO_PRI); 
    guint id = g_io_add_watch(channel, cond, onButtonEvent, 0); 

    g_main_loop_run(loop); 
} 

Als ich die GIOCondition-G_IO_IN die onButtonEvent läuft die ganze Zeit verändert haben mir den richtigen Wert von gpio zu geben, aber unendlich, ohne Stopp, weil (wie geschrieben here) g_io_add_watch in diesem Fall liest die Datei immer, wenn es Daten zu lesen gibt. Aber ich möchte die Daten nur lesen, wenn die Datei geändert wurde.

Ist es wirklich möglich, das mit G_IO_PRI, die das Ereignis aufrufen, wenn "es dringend Daten zu lesen" gibt? Und wann genau ist diese Bedingung erfüllt? Was kann mein Fehler sein?

Antwort

0

Wenn Sie eine Uhr hinzufügen auf einem GIOChannel mit der Bedingung G_IO_PRI wird es grundsätzlich dazu führen a poll() Anruf mit POLLPRI Flag. In der Dokumentation für den Linux-GPIO Sysfs Schnittstelle steht, dass:

Wenn der Stift als Interrupt-Erzeugungs Interrupt konfiguriert werden kann, und wenn Interrupts konfiguriert wurde zu generieren (siehe Beschreibung von „edge“) Sie können die Datei abfragen (2) und die Abfrage (2) wird immer dann zurückgegeben, wenn der Interrupt ausgelöst wurde. Wenn Sie Poll (2) verwenden, legen Sie die Ereignisse POLLPRI und POLLERR fest. Wenn Sie select (2) verwenden, setzen Sie den Dateideskriptor in exceptfds. Nach der Abfrage (2), entweder lseek (2) an den Anfang der sysfs-Datei zurück und lesen Sie den neuen Wert oder schließen Sie die Datei und öffnen Sie es erneut, um den Wert zu lesen.

Das bedeutet, dass G_IO_PRI auf dem GPIO auf Interrupts wird hören und das wiederum bedeutet, dass Sie den Stift konfigurieren Interrupts auf „none“ zu erzeugen, „steigend“, „fallen“ oder „both“ Kanten in 'sys/klasse/gpio/gpio/edge'. Wenn diese Datei nicht existiert, bedeutet dies, dass der GPIO die Interrupt-Erzeugung nicht unterstützt.

Also kurz gesagt; Ihr Code sollte funktionieren, da der GPIO die Interrupt-Generierung unterstützt und die korrekten Kanten aktiviert sind.