我正在尝试使用Gtk3 +来实现事件触发的串行端口读取。
当接收到数据时,GUI变得无响应。我认为在数据接收事件之后,循环不会转到gtk_main()。有时,数据流从串行端口上的发送方设备继续,GUI返回响应状态。
那么,从串行接收到一些字节后如何返回gtk_main(()循环?
这是我编写的代码;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <errno.h>
#include <termios.h>
#include <gtk/gtk.h>
void signal_handler_IO (int status); /* definition of signal handler */
volatile int n, fd;
volatile char buf [100];
int connected;
struct termios termAttr;
struct sigaction saio;
void UartInit(){
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd == -1)
{
perror("open_port: Unable to open /dev/ttyO1\n");
exit(1);
}
saio.sa_handler = signal_handler_IO;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO,&saio,NULL);
fcntl(fd, F_SETFL, FNDELAY);
fcntl(fd, F_SETOWN, getpid());
fcntl(fd, F_SETFL, O_ASYNC ); /**<<<<<<------This line made it work.**/
tcgetattr(fd,&termAttr);
//baudRate = B115200; /* Not needed */
cfsetispeed(&termAttr,B115200);
cfsetospeed(&termAttr,B115200);
termAttr.c_cflag &= ~PARENB;
termAttr.c_cflag &= ~CSTOPB;
termAttr.c_cflag &= ~CSIZE;
termAttr.c_cflag |= CS8;
termAttr.c_cflag |= (CLOCAL | CREAD);
termAttr.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
termAttr.c_iflag &= ~(IXON | IXOFF | IXANY);
termAttr.c_oflag &= ~OPOST;
tcsetattr(fd,TCSANOW,&termAttr);
printf("UART1 configured....\n");
//close(fd);
}
int main(int argc, char *argv[])
{
GtkWidget *main_window, *label, *image, *image_alt;
GtkWidget *main_box; /* VBox to hold main_hbox and the controls */
GtkWidget *controls; /* HBox to hold the buttons and the slider */
gtk_init(&argc, &argv); //Inititalize GTK
main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request(main_window, 480, 800);
label = gtk_label_new("deeneme");
//gtk_container_add(GTK_CONTAINER(window), label);
gtk_window_set_decorated(GTK_WINDOW(main_window), FALSE); //Hide menu bar
image = gtk_image_new_from_file("/home/x/Desktop/downArrow2.png");
image_alt = gtk_image_new_from_file("/home/x/Desktop/arcelik.png");
//gtk_container_add(GTK_CONTAINER(main_window), image);
controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start (GTK_BOX (controls), image, FALSE, FALSE, 50);
gtk_box_pack_start (GTK_BOX (controls), label, FALSE, FALSE, 0);
main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (main_box), controls, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (main_box), image_alt, FALSE, FALSE, 0); //altda ki image ekle
gtk_container_add (GTK_CONTAINER (main_window), main_box);
gtk_widget_show_all(main_window); //Show all widgets
// gtk_widget_hide(image);
UartInit(); //Initialize UART
gtk_label_set_markup(GTK_LABEL(label), "<span foreground=\"white\" size='300100'>1</span>"); //Set number color and size......1234
gtk_main(); //Start main loop
return 0;
}
void signal_handler_IO (int status)
{
int n = read (fd, &buf, sizeof buf);
if(n > 1)
{
buf[n] = '\0';
printf("Receive OK %s\n",buf);
}
}