关于等待在串行链路上读取的数据的通知

时间:2017-11-15 17:39:27

标签: c serial-port glib

我尝试在g_main_loop上添加一个新的源代码,它是一个外围串行线上的文件描述符。

我试试这段代码:

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

回调是:

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

当我在串行线上发送数据时,我获得了一个每次调用cb_1的无限循环。

我不知道我的错误在哪里,我预计在下一个g主循环迭代期间,串行线路的文件描述符内的读取将足以停止对回调的调用...

2 个答案:

答案 0 :(得分:1)

尝试在g_io_add_watch之后添加g_io_channel_unref(channel) immediatley。然后在你的回调中添加

if(G_IO_STATUS_EOF == status)
 return FALSE;
  

g_io_channel _ * _ new()返回GIOChannel   引用计数为1的对象。 g_io_add_watch()进一步增加了   引用计数 - 如果将其减1,则回调将为   断开连接并在回调时删除相关的GSource对象   返回FALSE,它在检测到文件结束时应该执行,或者是   你在g_io_add_watch()

的返回值上调用g_source_remove()

答案 1 :(得分:1)

在Linux上,GLib g_io_add_watch方法将您的文件描述符添加到poll()。 / dev文件上的轮询与套接字描述符或普通文件不同。检查驱动程序中的struct fops结构,以了解驱动程序是否支持轮询操作。除非您使用某些自定义驱动程序,否则通常它们会支持还要与任何其他/ dev文件交叉检查您的代码。

检查回调中g_io_channel_read_line返回的状态是否为G_IO_STATUS_AGAIN,这意味着资源暂时不可用;因此,您的文件描述符上发生了一个事件,但没有可立即从驱动程序缓冲区中读取的数据。