Serial Programming in POSIX

Serial Programming in POSIX

Post by Angel Galindo Mu?o » Thu, 23 Mar 2000 04:00:00



        Hello!

        I'm trying to communicate synchronously with a GSM-modem (really
doesn't matter what's on the other side of the Serial Port!) using
linux-Unix.
        My real problem is to do a synchronous serial communication with
whatever be connected to the serial port.

____________________________________
And I have opened the port this way:
____________________________________

{
int fd;
struct termios options,xivato;  /* doesn't use xivato ... ;-) */

bzero(&options,sizeof(struct termios));
bzero(&xivato,sizeof(struct termios));
tcgetattr(fd,&xivato);

fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY);  /* opens the
port */
fcntl(fd, F_SETFL, 0);
cfmakeraw(&options);
        /* which uses this flags with the termos structure:
                   termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
                                   |INLCR|IGNCR|ICRNL|IXON);
                   termios_p->c_oflag &= ~OPOST;
                   termios_p->c_lflag &=
~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
                   termios_p->c_cflag &= ~(CSIZE|PARENB);
                   termios_p->c_cflag |= CS8;
        */
tcsetattr(fd, TCSAFLUSH, &options);
return (fd);

Quote:}

__________________________
But I still have problems:
__________________________

        Doing it this way, I can  do this communication, so I can send AT
commands to the modem and I can read his answers but I've got already
two problems:

        -I can't do a blocking read: I mean that what I need is to call a
function to read which doesn't return until there's anything in the
buffer to be read, or which could wait for a little time  (I could read
untill the data read is not null, but I prefer do it right!).   (I've
tried to un-use the "O_NDELAY" flag, but this doesn't seem to work at
all!)

        -The program I've wrote runs right once, but I want to run it a second
time, the program blocks trying to read the answer to the firs "AT\r"
command which I send to initialize the modem. When this happens, I've to
run "minicom" and re-initialize the modem, this evidently is not valid
to my program and also means that my program is not good!!!!

_____________________________
Some resources of information
_____________________________

        The links in which I have found some interesting information are:

http://www.prairienet.org/~rmasoner/serial.html
http://mops.uci.agh.edu.pl/doc/Linux-mini-HOWTOs/Serial-Port-Programming
http://www.linuxdoc.org/HOWTO/Modem-HOWTO.html
http://www.linuxdoc.org/HOWTO/Serial-Programming-HOWTO.html
http://www.easysw.com/~mike/serial

______________________
That's what I need ;-)
______________________

        ?Does anybody has already done something like this? ?Can I take a look
to this code?
        ?Does someone know how can I do this "blocking read" or what's the
matter that I cannot read anymore once I've executed the program once?
        ?Does anybody know any other resource of information, any link, any
book... anything?

        I have no problem to give the C's source of what I've done to anybody
who also has to do something like this and doesn't want to start from
zero.

        I'm waiting for some holy answer ...    Thanks in advance!!!

Angel Galindo Mu?oz

 
 
 

Serial Programming in POSIX

Post by Tony R. Benne » Thu, 23 Mar 2000 04:00:00




 >
 >   Hello!
 >
 >   I'm trying to communicate synchronously with a GSM-modem (really
 >doesn't matter what's on the other side of the Serial Port!) using
 >linux-Unix.
 >   My real problem is to do a synchronous serial communication with
 >whatever be connected to the serial port.
 >
 >____________________________________
 >And I have opened the port this way:
 >____________________________________
 >
 >{
 >int fd;
 >struct termios options,xivato;     /* doesn't use xivato ... ;-) */
 >
 >bzero(&options,sizeof(struct termios));
 >bzero(&xivato,sizeof(struct termios));
 >tcgetattr(fd,&xivato);
 >
 >fd =3D open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY);  /* opens the
 >port */
 >fcntl(fd, F_SETFL, 0);
 >cfmakeraw(&options);
 >   /* which uses this flags with the termos structure: =
 >
 >              termios_p->c_iflag &=3D ~(IGNBRK|BRKINT|PARMRK|ISTRIP =
 >
 >                                   |INLCR|IGNCR|ICRNL|IXON);
 >                   termios_p->c_oflag &=3D ~OPOST;
 >                   termios_p->c_lflag &=3D
 >~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
 >                   termios_p->c_cflag &=3D ~(CSIZE|PARENB);
 >                   termios_p->c_cflag |=3D CS8;
 >   */
 >tcsetattr(fd, TCSAFLUSH, &options);
 >return (fd);
 >}
 >
 >
 >__________________________
 >But I still have problems:
 >__________________________
 >
 >   Doing it this way, I can  do this communication, so I can send AT
 >commands to the modem and I can read his answers but I've got already
 >two problems:
 >
 >   -I can't do a blocking read: I mean that what I need is to call a
 >function to read which doesn't return until there's anything in the
 >buffer to be read, or which could wait for a little time  (I could read
 >untill the data read is not null, but I prefer do it right!).   (I've
 >tried to un-use the "O_NDELAY" flag, but this doesn't seem to work at
 >all!)
 >
 >   -The program I've wrote runs right once, but I want to run it a second
 >time, the program blocks trying to read the answer to the firs "AT\r"
 >command which I send to initialize the modem. When this happens, I've to
 >run "minicom" and re-initialize the modem, this evidently is not valid
 >to my program and also means that my program is not good!!!!
 >
 >
 >_____________________________
 >Some resources of information
 >_____________________________
 >
 >   The links in which I have found some interesting information are:
 >
 >http://www.prairienet.org/~rmasoner/serial.html
 >http://mops.uci.agh.edu.pl/doc/Linux-mini-HOWTOs/Serial-Port-Programming
 >http://www.linuxdoc.org/HOWTO/Modem-HOWTO.html
 >http://www.linuxdoc.org/HOWTO/Serial-Programming-HOWTO.html
 >http://www.easysw.com/~mike/serial
 >
 >
 >______________________
 >That's what I need ;-)
 >______________________
 >
 >
 >   =BFDoes anybody has already done something like this? =BFCan I take a lo=
 >ok
 >to this code?
 >   =BFDoes someone know how can I do this "blocking read" or what's the
 >matter that I cannot read anymore once I've executed the program once?
 >   =BFDoes anybody know any other resource of information, any link, any
 >book... anything?
 >
 >
 >   I have no problem to give the C's source of what I've done to anybody
 >who also has to do something like this and doesn't want to start from
 >zero.
 >
 >
 >   I'm waiting for some holy answer ...    Thanks in advance!!!
 >
 >
 >Angel Galindo Mu=F1oz

Angel,

    After doing your open, ioctl() (which I assume is what cfmakeraw()
    does) and tcsetattr() How about calling fcntl to turn OFF
    delay???

        i.e.:
        fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY);

    As for the 'timed read'... check out "man select".

    Oh, and be sure to 'reset' the terminal before exiting...

        struct term;

        ioctl(fd, TCGETA, &term);  /* save it...*/

        ioctl(fd, TCSETA, &term);  /* reset it... prior to exiting */

HTH,
Tony
--



 
 
 

1. Serial programming problems (POSIX)

Hi.  I am trying to develop a primitive 'cu' command on Linux, much
like the one that is available on SVR4 systems, and I've had partial
success. My aim is to remain fully POSIX in my programming and I would
like to (if possible) try to stay away from any non-POSIX way of
accessing the serial ports.

What I did in my program which I do not have at hand was like this
(pseudo code):

portfd=open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK);
[checks here for success...]
tcgetattr(portfd);
cfsetispeed/cfsetospeed(portfd);
cfmakeraw(portfd);
tcsetattr(portfd);

then (here's where my trouble begins):

while (1)
{
        char ch, buf[1024];
        cnt = read(portfd, buf, 1024);
        [if cnt != 0, then I echo the characters to the terminal,
meaning that there was something coming back from the serial port,
i.e. an OK from the modem]]
        cnt = read(STDIN_FILENO, &ch, 1); // get kbd input
        [checks here for success...]
        write(portfd, &ch, 1);                  // send it right away on a
char by char basis to the port
        [checks here for success...]

Now, when I did something like this, don't remember the EXACT code, I
managed to be able to issue commands to the port, however, everything
I typed was echoed back a character later. I.E. if I wanted to issue
an AT\r, I'd hit A, then nothing would be echoed back (and it
supposedly should be echoed back at the beginning of the loop on the
next iteration), and then when I'd hit the T, the A would be echoed
back to me, then I'd hit <Enter>, then the T would be echoed back, and
then I'd finally hit <enter> or some other key, and the OK result
would be echoed back to me.

What am I doing wrong here?  Do I need to have separate processes that
will handle keyboard input and serial port output or no? I was looking
at some MINICOM code and it looks like he's managing to do all this in
a single while (1) loop, using select() and not having to fork
separate processes for keyboard handling or for ser. output handling.

Can someone experienced more than I tell me what is the _correct_, by
the book way, of doing this sort of thing, that is, handling serial
input and output mixed with keyboard input?  Do I need separate
processes ? I booted 'cu' on an SVR4 machine, it looked like it was
forking twice, which makes me think the correct way of doing this now
is to use 2 processes, one for kbd input, one for ser. output
handling? I have no experience in this area so any books recommended
would help, or at least some unix lovers' :-) advice would help.

Please help.
thank you.
Martin
p.s. what I really want to eventually do is write up an API for my
Kodak DC210 camera, which what I'll do once I learn proper RS232
handling techniques and give the API source away for free to support
Linux and POSIX at the same time. I just need a little boost on rs232
techniques :-).

Thanks.

2. Multiple Cards

3. POSIX Serial programming problem

4. ppp

5. Serial Programming in POSIX

6. Hercules Video

7. POSIX Serial Programming

8. Help: AccelX installation

9. How to set up serial port when programming serial communication

10. Parallel Port programming question, was "Serial Port Programming"

11. serial port access on POSIX

12. POSIX.1 method of setting serial communications speed above 38400 Baud