2017-11-15 1 views
0

Ich versuche, zu meinem g_main_loop eine neue Quelle hinzuzufügen, die ein Dateideskriptor auf einer peripheren seriellen Leitung ist.Benachrichtigung über Daten, die darauf warten, auf der seriellen Verbindung gelesen zu werden

Ich versuche, diesen Code:

GError* error; 
GIOChannel* channel; 
channel=g_io_channel_unix_new(fd_serial_line_dev); 
g_io_add_watch(channel, G_IO_IN, cb_1, NULL); 
g_io_channel_set_close_on_unref(channel, TRUE); 
g_io_channel_set_encoding(channel, NULL, &error); 
g_io_channel_set_buffered(channel, FALSE); 

Der Rückruf ist:

gboolean cb_1 (GIOChannel *source, GIOCondition condition, gpointer data) 
{ 
    gchar** line=NULL; 
    GIOStatus status; 
    GError* error; 

    printf("cb\n"); 

    status=g_io_channel_read_line(source, line, NULL, NULL, &error); 

    if(G_IO_STATUS_NORMAL == status) 
    { 
    printf("callback : data : %s\n", *line); 
    g_free(*line); 
    //g_io_channel_seek_position(source, 0, G_SEEK_CUR, NULL); 
    } 

    return TRUE; 
} 

Wenn ich Daten auf der seriellen Leitung schicken, ich eine Endlos-Schleife zu erhalten, die jede CB_1 Zeit nennen.

Ich sehe nicht, wo mein Fehler ist, erwartete ich, dass eine innerhalb Dateideskriptor der seriellen Leitung lesen stoppt während der nächsten g Haupt Schleifeniterationslatenzzeit an die Callback werden süffisant nennen ...

+0

Von dem, was ich verstehe, sollten Sie auf einen Fehler zurückgeben, um den Kanal zu schließen. – TheAschr

+0

Ich versuche und mit dieser Lösung wird Callback nie aufgerufen werden, auch wenn ein neues Zeichen kommt. Für mich ist die Rückgabe von FALSE nützlich, wenn die Ereignisquelle entfernt werden soll –

Antwort

1

Unter Linux GLib g_io_add_watch Methode fügt Ihren Dateideskriptors abzufragen(). Poll on/dev-Dateien ist nicht dasselbe wie Sockets-Deskriptoren oder normale Dateien. Überprüfen Sie in Ihrem Treiber die struct-fops-Struktur, um zu ermitteln, ob der Abfragevorgang von Ihrem Treiber unterstützt wird oder nicht. Normalerweise werden sie unterstützt, es sei denn, Sie verwenden einen benutzerdefinierten Treiber. Überprüfen Sie auch Ihren Code mit einer anderen/dev-Datei.

Überprüfen Sie, ob der Status von g_io_channel_read_line im Rückruf G_IO_STATUS_AGAIN ist, dessen mittlere Ressource vorübergehend nicht verfügbar ist; Es ist also ein Ereignis in Ihrem Dateideskriptor aufgetreten, aber es sind keine unmittelbaren Daten zum Lesen aus den Treiberpuffern verfügbar.

1

Try Hinzufügen von g_io_channel_unref(channel) immediatley nach g_io_add_watch. Dann in Ihrem Rückruf hinzufügen

if(G_IO_STATUS_EOF == status) 
return FALSE; 

g_io_channel _ * _ new() gibt ein GIOChannel Objekt mit einem Referenzzähler ein. g_io_add_watch() fügt einen weiteren Referenzzähler hinzu - wenn Sie ihn um 1 dekrementieren, wird der Callback getrennt und das entsprechende GSource-Objekt entfernt, wenn der Callback FALSE zurückgibt, was er tun sollte, wenn er das Dateiende erkennt wenn Sie g_source_remove() auf dem Rückgabewert von g_io_add_watch nennen()

Verwandte Themen