I am just starting programming for Linux and right now I have a wish to trigger some event when the external button connected to Beaglebone is pressed. Here I have found a nice solution based on Glib and tried to implement it. But unfortunately the event is triggered only once at the beginning and then no matter how many times I press the button it doesn't react.
Here is the code taken exactly from the tutorial:
#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 );
}
When I have changed the GIOCondition to G_IO_IN the onButtonEvent runs all the time giving me the correct value of gpio, but infinitely, without a stop, because (as written here) g_io_add_watch in this case reads the file always when there is data to read. But I want to read the data only when the file was changed.
Is it really possible to make that with G_IO_PRI which invoke the event when "there is urgent data to read"? And when exactly this condition is satisfied? What can be my mistake?