ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Hi,
I know how to do a basic serial communication prgram. I am trying to make the interface graphical.
For starters I have my serial program serial.c and serial.h
I have created a gtk interface. when I press my button I need to initialise and send a string. I tried to include the serial.h header in this file and made a function for the gtk_signal_connect call. here i tried to initialise and send my command. It does not seem to work. I tried to look up simliar stuff on the net but am unable to understand the gtkterm project. Can someone please help me with this.
If this works I am sure I can have an input and output side text box. But for now am stuck. Can someone help!!
Thanks
Prem
does your serial.c and serial.h works without a gui ?
how you code your button pressed "events" ?
if possible show them the gtk_signal_connect code .....
they might need some code inorder to help you ...........
include<stdio.h>
#include<string.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include "serial.h"
/*
file-scope variable to save terminal settings
*/
struct termios oldtermios; /* to save original settings */
/*
Function implementations:
serial_open () takes the port number and the baud and returns
an open file descriptor, or -1 = failed, -3 = other error.
*/
int
serial_open (int port_no, int baud)
{
int fd; /* file descriptor of the port */
char *name = "/dev/ttyS0";
int b_baud;
struct termios t; /* struct for port settings */
/* convert to port and baud input */
switch (port_no)
{
case 2:
name = "/dev/ttyS1";
break;
case 3:
name = "/dev/ttyS2";
break;
case 4:
name = "/dev/ttyS3";
break;
default:
name = "/dev/ttyS0";
break;
}
switch (baud)
{
case 4800:
b_baud = B4800;
break;
case 9600:
b_baud = B9600;
break;
case 19200:
b_baud = B19200;
break;
case 38400:
b_baud = B38400;
break;
case 57600:
b_baud = B57600;
break;
case 115200:
b_baud = B115200;
break;
default:
b_baud = B9600;
break;
}
fd = open (name, O_RDWR | O_NOCTTY );
if (fd < 0)
return -1; /* open failed */
if (tcgetattr (fd, &t) != 0) {
return (-3);
}
/*
save old settings
*/
oldtermios = t;
/*
do settings
*/
t.c_cc[VMIN] = 32;
t.c_cc[VTIME] = 1;
t.c_cflag |= CLOCAL | CREAD | CS8;
/* copy data rates into termios struct */
if (cfsetispeed (&t, b_baud) == -1)
{
return (-3);
}
if (cfsetospeed (&t, b_baud) == -1)
{
return (-3);
}
/* throw away any input data / noise */
if (tcflush (fd, TCIFLUSH) == -1)
{
return (-3);
}
/* Now, set the terminal attributes */
if (tcsetattr (fd, TCSANOW, &t) == -1)
{
return (-3);
}
return fd;
}
/*
serial_close () resets then closes port of file descriptor fd.
*/
int
serial_close (int fd)
{
/* reset port to old settings and return */
tcsetattr (fd, TCSANOW, &oldtermios);
close (fd);
return 0;
}
/*
serial_bytes_waiting () returns the number of bytes waiting to be read
at the port described by fd.
*/
int
serial_bytes_waiting (int fd)
{
int bytes;
ioctl (fd, FIONREAD, &bytes); /*read number of bytes in input buffer*/
return bytes;
}
/*
The serial_read () and serial_write () are simple wrappers.
serial_write () writes the string pointed to by buf, up to n chars.
serial_read () reads up to n chars and puts it into buf.
*/
int
serial_write (int fd, char *buf, int n)
{
int bytes_written = write (fd, buf, n);
return bytes_written;
}
int
serial_read (int fd, char *buf, int n)
{
int bytes_read = read (fd, buf, n);
return bytes_read;
}
/*
end of serial.c
*/
int main ()
{
int st1,st2,st3,st4,st5;
char out_buffer[100];
char *op;
int size;
char *ip[26];
op = (char *)memset(out_buffer, '\0', 100);
st1=serial_open(1,9600);
st2=serial_open(2,9600);
printf("File descirptor for port 1 %d\n",st1);
printf("File descriptor for port 2 %d\n",st2);
ip[0]="123SMD990bbbbb\r";
size=strlen(ip);
printf(" String: %s\n",ip);
printf("Its length is %d\n",size);
printf("number of bytes in com2 buffer is %d and com1 buffer is %d\n",
st3,st4);
op = (char *)memset(out_buffer, '\0', 100);
st5=serial_read (st2, op,size);
printf("\nnumber of bytes in reader buffer %d ",st5);
printf("\nRecieved word is %s\n",op);
serial_close (st1);
serial_close (st2);
}
and I am able to both send and recive data without any problem.
In the same directory I have created my graphics program.
sergra.c
#include<gtk/gtk.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include "serial.h"
}
I amn not even able to open the port!! Shouldnt I be simply ablt to include my header serial.h ( where I have defined my function ) and directly be able to use it in the gtk program. I will really appreciate it if someone responds . Unfortunately I have had a look at the gtkterm project but could not make out head or tail.am hence trying to take this one step at a time
prem
although i never do gtk before and since there's full code
so i try to compile it and have some fun out of it
it's seem to be able to compile for me or maybe i'm doing it the wrong way or some other , these are the results without gui and with gtk :
result without gui :
Code:
File descirptor for port 1 3
File descriptor for port 2 -3
File descriptor for port 3 -3
File descriptor for port 4 -3
String: 123SMD990bbbbb
Its length is 15
number of bytes in com1 buffer is 15
result with gtk :
Code:
File descirptor for port 1 6
File descriptor for port 2 -3
File descriptor for port 3 -3
File descriptor for port 4 -3
String: 123SMD990bbbbb
Its length is 15
number of bytes in com1 buffer is 15
alred,
How did you compile the code. My guess is that you just compiled serial.c two times. Basically what am doing is defining open port etc etc in serial .h. The gtk porgram is sergra.c where I have defined a button this is the file that needs to be complied . If I click this button I am hoping that I can call my intit port function since I am including serial.h header in sergra.c. Anyways I just hope someone who know these thing can help me out!
Alred,
Thanks a lot, your file organisation seems to right. But I am still stuck . I tried mimicking exactly what you did. However I seem to have a few problems.
this is what I did
gcc -c serial.c
gcc -shared -o libserial.so serial.o
gcc -L. -lserial -o ser ser.c
gcc `pkg-config --cflags --libs gtk+-2.0` -L. -lserial serGTK.c -o serGTK
where serial.c is the function definitions,
ser.c is my main program
and serGTK is the graphics program.
I do not get any errors for any of them
.
But when i try to execute them
./ser or
./sergra i get an error:
error while loading shared libraries: libserial.so : cannot open shared object file: No such file or directory exists. However this file very much exists . All files are in the same directory. Hope you help me cause I seem totally stuck !!!
Works!. Thanks a lot alred. Just one more point.( its more out of academic interest really) why do I need to share it in this way. For normal library functions I created All I need to do is to include the header, whereas here am creating a dynamic share.
its still possible to just include headers in the main app but it just make your source more readable by breaking large source file into multiple sources especially you have a lot of global declations of #define or variables
with dynamic shared lib we have app which is more re-usable . That mean we need just to "upgrade" that particular library source and re-complie as shared and redistribute that particular shared library only , no need to touch and redistribute the main app and source . This works fine if we can break down our app into many manageble "components" as shared libraries , with this method the main source actually functions as a glueing board for our components/shared libraries.
Furthermore if programmers using languages other the C need your serial library functions in their own app , then they only need to port your headers file to their language of choice , compile it with their language compiler , then they can call your serial functions in their own program .
i'm using only Kylix/Pascal when comes to programming and there are lots of well known headers files in linux which have been ported to Pascal headers like xine.h , smpeg and sdl.h , therefor Kylix/Pascal programmers can still call XINE , SMPEG and SDL functions in their app . infact i had tried porting your serial.h to serial.pas , compile it with Kylix and i'm able to call your serial functions in Kylix/Pascal program for testings .
this is how i understand C shared libraries , hopes that i'm not too wrong with this .
as for the actual answer , i believe those real-world C programmers are in a better position to give you a better answer .
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.