2016-07-29 18 views
0

我刚刚开始为Linux编程,现在我希望在连接到Beaglebone的外部按钮被按下时触发某些事件。 Here我发现了一个基于Glib的很好的解决方案,并试图实现它。但不幸的是,事件一开始只触发一次,然后无论我按下按钮多少次都没有反应。GIocondition G_IO_PRI用于按Beaglebone上的按钮不被满足

下面是本教程究竟采取代码:

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

当我已经改变了GIOConditionG_IO_INonButtonEvent运行所有的时间给我的GPIO正确的值,但无穷无尽,因为(如写作hereg_io_add_watch在这种情况下总会在有数据读取时读取文件。但我只想在文件被更改时读取数据。

是否真的有可能通过G_IO_PRI在“有紧急数据要读取”时调用事件?当这个条件满足时?什么是我的错误?

回答

0

如果添加监视在GIOChannel与条件G_IO_PRI它将基本上导致poll()POLLPRI通话。在为Linux GPIO SYSFS的文档界面,它说的是:

如果引脚可以被配置为生成中断的中断和 ,如果它已经被配置为产生中断(见的“边缘”的 描述) ,您可以轮询(2)该文件,而轮询(2) 将在中断被触发时返回。如果使用轮询(2) ,请设置事件POLLPRI和POLLERR。如果使用select(2),则 会在exceptfds中设置文件描述符。 poll(2)返回后,将 lseek(2)返回到sysfs文件的开头,并读取新值 或关闭文件并重新打开它以读取该值。

这意味着,G_IO_PRI会听中断的GPIO而这又意味着你必须配置引脚上产生“无”中断“上升”,“下降”或“既”边缘在'sys/class/gpio/gpio/edge'中。如果该文件不存在,则意味着GPIO不支持中断产生。

所以总之;如果GPIO支持中断产生并且启用了正确的边沿,则代码应该工作。