This is a multi-part message in MIME format.
--------------000902080100000806010905
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
I guess this can help. It's from a HOWTO, I just updated the include
file names to be compatible to the newer glibc
Francisco
Herbert Graf wrote:
>Hello all,
>
>I'm trying to write a small program that sends a few things over a serial
>port and then reads a few things back. I've having trouble getting it to
>work.
>
>I'm using open, write and read to do my things, accessing the device through
>the /dev/ttyS1 interface. Things work fine for a while and then seem to go
>crazy. For example, I can send a few things down the line, but then when I
>do a single byte read from the port I continuously get the newline
>character.
>
>Anybody have some simple gcc compatible c code of accessing the serial port
>in Linux? I'm using Redhat 9.0 and gcc. Thanks, TTYL
>
>----------------------------------
>Herbert's PIC Stuff:
>http://repatch.dyndns.org:8383/pic_stuff/
>
>--
>http://www.piclist.com hint: PICList Posts must start with ONE topic:
>[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
>
>.
>
>
>
--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
--------------000902080100000806010905
Content-Type: text/x-csrc;
 name="miniterm.c"
Content-Disposition: inline;
 filename="miniterm.c"
Content-Transfer-Encoding: quoted-printable
X-MIME-Autoconverted: from 8bit to quoted-printable by telcommail.net id i1GL4vEL074137
/*!
 *  \file miniterm.c
 *  \author Sven Goldt (goldt@math.tu-berlin.de)
 *
 *  \brief  RS232 controllable device terminal 
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  This is like all programs in the Linux Programmer's Guide meant
 *  as a simple practical demonstration.
 *  It can be used as a base for a real terminal program.
 * =20
 * updated for newer include files for glibc 2.3.1
 * by Francisco J. A. Ares (frares@netscape.net)
 *
 * updated to work with RS232 controllable device
 * by Francisco J. A. Ares (frares@netscape.net)
 */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
/*! \brief Defini=E7=E3o da velocidade a ser usada      */
#define BAUDRATE B9600
/*! \brief Ctrl-D =E9 usado para sair do \b miniterm    */
#define ENDMINITERM     4
/*! \brief Caractere de retorno de carro        */
#define CRETURN 0x0d
/*! \brief Caractere de avan=E7o de linha       */
#define NLINE 0x0a
/*! \brief Defini=E7=E3o de l=F3gica bin=E1ria para \b FALSE    */
#define FALSE 0
/*! \brief Defini=E7=E3o de l=F3gica bin=E1ria para \b TRUE     */
#define TRUE 1
/*! \brief Indicativo de finaliza=E7=E3o do processo \a child   */
volatile int STOP=3DFALSE;=20
/*! \brief Usado para convers=E3o \a decimal / \a hexa  */
int     hex[16] =3D { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', =
'B', 'C', 'D', 'E', 'F' };
/*! \brief Dispositivo serial padr=E3o  */
char SerialDevice[20] =3D "/dev/ttyS1";
/*! \brief Comportamento padr=E3o de envio de \a CRC            */
char SendCRC =3D FALSE;
/*! \brief N=FAmero padr=E3o de caracteres a serem enviados     */
int     CharsToSend =3D 0;
/*! \brief N=FAmero padr=E3o de caracteres a ser recebido antes de operar=
 um \a EOL      */
int CharsToGet =3D 0;
/*! \brief Estruturas de configura=E7=E3o da interface \b RS232 */
struct termios oldtio, newtio, oldstdtio, newstdtio;
/*! \brief Estrutura de defini=E7=E3o dos sinais do processo \a child */
struct sigaction sa;
/*! \brief Buffer com apenas 16 \a bytes de tamanho     */
int     outbuf[16];
/*! \brief Descritor de arquivo para manipular a interface serial       */
int fd;
/*! \brief \a Handler para o fim do processo \a child   */
void child_handler(int s)
{
        STOP=3DTRUE;
}
/*! \brief interpretador da linha de comando    */
void CommandLineInterpreter(int argc, char *argv[])
{
/*! \brief Contador auxiliar    */
int     i;
        if ( ( argv[1] =3D=3D "--help"  ) || ( argv[1] =3D=3D "-h" ) )
        {
                perror("miniterm [-d ] [-c] [-ns ] [-nr <=
count to receive>]");
                exit (-1);
        }
        else
        {
                for (i=3D1;i0)
                printf ( "Sending %d chars\n", CharsToSend);
        else
                puts ( "Sending chars until ");
        if (CharsToGet>0)
                printf ( "Receiving %d chars\n\n", CharsToGet);
        else
                puts ( "Receiving chars until \n");      /*      "puts" already sends a ne=
wline, and I want another one   */
/* terminal settings done, now handle in/ouput */
        switch (fork())
        {
                case 0: /* child */
/* user input */
                        c1=3Dgetchar();
                        while ( c1 !=3D ENDMINITERM )
                        {
                                if ( c1 !=3D ENDMINITERM )
                                {
                                        if ( CharsToSend > 0)
                                        {
/* hex digits, fixed number of bytes to be sent */
                                                for ( ac =3D 0; ac < (SendCRC?CharsToSend-1:CharsToSend); ac++ )
                                                {
/* get hex digits       */
                                                        write(1,&c1,1);                 /* stdout */
                                                        c2 =3D getchar();
                                                        write(1,&c2,1);
/* converts two nibble chars to one only byte   */
                                                        c1=3D ( ( c1 < 0x3a ?
                                                                        c1 & 0x0f :
                                                                        ( c1 & 0x5f ) + 9 - 0x40 )
                                                                << 4 ) |
                                                                        ( c2 < 0x3a ?
                                                                        c2 & 0x0f :
                                                                        ( c2 & 0x5f ) + 9 - 0x40 ) ;
/* put new byte in buffer       */
                                                        outbuf[ac] =3D c1;
/* separating hex digits on stdout (screen, basically)  */
                                                        c2 =3D ' ';
                                                        write(1,&c2,1);
/* done with all bytes? */
                                                        if (ac !=3D (SendCRC?CharsToSend-2:CharsToSend-1) )
                                                                c1 =3D getchar();
                                                }
/* send bytes and calculate check summ  */
                                                ac =3D 0;
                                                for ( c2 =3D 0 ; c2 < (SendCRC?CharsToSend-1:CharsToSend) ; c2++ )
                                                {
                                                        c1 =3D outbuf[c2];
                                                        ac +=3D c1;
                                                        write(fd,&c1,1);
                                                }
                                        }
                                        else
                                        {
/* typed chars are the bytes to be sent */
                                                c2 =3D 0;
/* done with all bytes? */
                                                while (c1 !=3D NLINE)
                                                {
/* put new byte in buffer       */
                                                        outbuf[c2] =3D c1;
                                                        write(1,&c1,1);         /* stdout */
                                                        c2++;
                                                        c1 =3D getchar();
                                                }
/* text delimiters to external device   (maybe some more command line param=
eters here)     */
                                                outbuf[c2] =3D CRETURN;
                                                c2++;
                                                outbuf[c2] =3D NLINE;
                                                c2++;
                                                outbuf[c2] =3D 0;
/* send bytes and calculate check summ  */
                                                ac =3D 0;
                                                c2 =3D 0;
                                                c1 =3D outbuf[c2];
                                                while (c1 !=3D NLINE)
                                                {
                                                        c1 =3D outbuf[c2];
                                                        ac +=3D c1;
                                                        write(fd,&c1,1);
                                                        c2++;
                                                }
                                        }
/* common part for both ways of typing bytes/chars      */
                                        if (SendCRC)
                                        {
/* separating digits on stdout (screen, basically)      */
                                                c2 =3D ' ';                     /*      extra space to checksum byte    */
                                                write(1,&c2,1);
                                                write(fd,&ac,1);        /*      serial device   */
/* converts one byte to two hex nibbles */
                                                c2 =3D hex[ ( ac & 0xf0 ) >> 4 ];       write(1,&c2,1);
                                                c2 =3D hex[ ac & 0x0f ];                        write(1,&c2,1);
                                        }
/* separating (at least trying to) input / output       */
                                        c2 =3D ' ';
                                        write(1,&c2,1);
                                        c2 =3D '-';
                                        write(1,&c2,1);
                                        c2 =3D ' ';
                                        write(1,&c2,1);
/* delay - have to find something better        */
                                        for ( c1 =3D 0; c1 <=3D 0x1fff; c1++)
                                                for ( c2 =3D 0; c2 <=3D 0x1fff; c2++)
                                                                ;
/* new line on display  anyhow, no matter if I get one through the serial       =
*/
                                        c2 =3D NLINE;
                                        write(1,&c2,1);
                                        c1=3Dgetchar();
                                }
                        }
/* gracefully quit, child part  */
                        tcsetattr(fd,TCSANOW,&oldtio);          /* restore old modem setings */
                        tcsetattr(0,TCSANOW,&oldstdtio);        /* restore old tty setings */
                        close(fd);
                        exit(0);        /* will send a SIGCHLD to the parent */
                        break;
                case -1:
                        perror("fork");
                        tcsetattr(fd,TCSANOW,&oldtio);
                        close(fd);
                        exit(-1);
                default: /* parent */
/* stdin not needed */
                        close(0);
/* handle dying child */
                        sa.sa_handler =3D child_handler;
                        sa.sa_flags =3D 0;
                        sigaction(SIGCHLD,&sa,NULL);
/* serial device input handler */
                        while (STOP=3D=3DFALSE)
                        {
                                read(fd,&c1,1);         /* serial device */
                                if (STOP=3D=3DFALSE)
                                {
                                        if (CharsToGet !=3D  0)
                                        {
/* hex digits, fixed number of bytes to be received     */
/* converts one byte to two hex nibbles */
                                                c2 =3D hex[ ( c1 & 0xf0 ) >> 4 ];
                                                write(1,&c2,1);
                                                c2 =3D hex[ c1 & 0x0f ];
                                                write(1,&c2,1);
                                                c2 =3D ' ';
                                                write(1,&c2,1);
/* done with all bytes? */
                                                if ( ++ac =3D=3D CharsToGet)
                                                {
                                                        c2 =3D NLINE;
                                                        write(1,&c2,1);         /* stdout */
                                                        ac =3D 0;
                                                }
                                        }
                                        else
                                        {
/* bytes received are just echoed to stdout     */
                                                if ( ( c1 =3D=3D NLINE ) || ( c1 =3D=3D CRETURN) )
                                                        c1 =3D ' ';
                                                write(1,&c1,1);         /*      stdout  */
                                        }
                                }
                        }
/* gracefully quit, parent part */
                        c2 =3D NLINE;
                        write(1,&c2,1);         /* stdout */
                        close(1);
/* wait for child to die or it will become a zombie */
                        wait(NULL);
                        break;
        }
        return (0);
}
/*! \test
 * Mitsubishi camera example:=20
 *=20
 * - program command line:                              miniterm -d /dev/ttyS1
 *=20
 * - manual iris adjust RS232 command:  "IRM-30"  ...  "IRM+30"   followed=
 by CR + LF (using  as end of input)
 *=20
 * - expected answer:                                   "RE" + CR + LF + "SE0007" + CR + LF
 *=20
 * - screenshot:
 *=20
 * IRM17 - RE
 *=20
 * SE0007
 *=20
 *=20
 * IRM18 - RE
 *=20
 * SE0007
 *=20
 *=20
 * IRM31 - ERR1
 *=20
 * IRM30 - RE
 *=20
 * SE0007
 *=20
 *=20
 *=20
 * Another camera example:
 *=20
 * - program command line:              miniterm -d /dev/ttyS1 -ns 6 -nr =
9 -c
 *=20
 * - manual iris adjust RS232 command:  c5 aa 7c  00  
 *=20
 * - expected answer:                   c5 aa 7c  7c XX XX XX=
                   ( XX means don't care )
 *=20
 * - screenshot:
 *=20
 * c5 aa 7c df 00  CA - C5 AA 7C DF 7C 07 04 56 A7
 *=20
 * c5 aa 7c ff 00  EA - C5 AA 7C FF 7C 07 04 56 C7
 *=20
 *=20
 * note that when the checksum is in use, it is one of the number
 * of bytes to be sent specified on the command line parameter.
 *=20
 * crtl-D exits from the program at the beginning of a new command.
*/
--------------000902080100000806010905--