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--