Re: serial port question.



chris dewbery <chris.dewbery@xxxxxxxxxxxxxx> wrote:
here is a snippet of code which sets the serial port to
19200 8E1. where fd is the file descriptor for the open serial port.

int fd = open( "/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY );

For portability, O_NONBLOCK is preferred over O_NDELAY. They
are exactly identical on Linux (and most other systems), but
have subtle differences on some platforms that make O_NDELAY
non-portable.

struct termios options;

memset(&options, 0, sizeof( struct termios ) );

/* set baud rate to 19200 */
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);

options.c_cflag |= (CLOCAL | CREAD);

Why use an OR function, when you know that the initial value
is 0?

options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD; /* Even parity */
options.c_cflag &= ~CSTOPB; /* 1 Stop bit */
options.c_cflag &= ~CSIZE;

Why clear bits, when the initial value is 0?

options.c_cflag |= CS8; /* 8 data bits */

options.c_cflag &= ~CRTSCTS;

All of the above can be a one liner:

options.c_cflag = (CLOCAL | CREAD | CS8 | PARENB);


options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

options.c_iflag |= (IGNPAR); /* Ignore parity */

Why enable parity and then ignore it on input?

options.c_iflag &= ~(IXON | IXOFF | IXANY);

tcsetattr(fd, TCSANOW, &options);

This call really should be checked for an error return.

tcflush( fd, TCIOFLUSH );

This call should probably be done prior to calling tcsetattr().

you should then be able to just send and receive data by using the
commands.

Note that you have left the port in non-blocking mode. Likewise
the termios settings are for raw mode and the VTIME and VMIN
elements of the c_cc array are 0. That is usable configuration
to be sure, but the code to read and write to the port is very
dependent upon that configuration, and when used as an example
that should be explicitly pointed.

write( fd, buffer, length );

The return value of write(2) is important, and this call
necessarily must be in a loop (unless "length" is 0). If a
value of -1 is returned the value of errno has to be checked to
determine if the loop should continue or not. The write
function also may or may not write the entire block of bytes
specified by "length", and the loop must handle short writes.

Given the non-blocking and raw mode configuration, the loop
should also include a delay between non-productive calls to
avoid hogging the CPU.

bytes = read( fd, buffer, sizeof(buffer));

This also needs to be called in a loop, for the same reasons as
apply to the write(2) function.

--
Floyd L. Davidson <http://www.apaflo.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska) floyd@xxxxxxxxxx
.



Relevant Pages

  • DCB Setup disagreeing with SetCommState
    ... I am having a problem configuring a certain port on my computer. ... want to loop through a list of active ports and listen to the one that ... configure the ports with //./COMx configuration, ... ....//Loop to cycle through active ports ...
    (microsoft.public.dotnet.languages.vc)
  • Spurious completions during NCQ
    ... support DPO or FUA ... ACPI: PM-Timer IO Port: 0x408 ... Using ACPI for SMP configuration information ...
    (Linux-Kernel)
  • sata_nv times out for BD-ROM iHOS104-08
    ... ata3: nv: skipping hardreset on occupied port ... configuration follow. ... 00:0e.0 RAID bus controller: nVidia Corporation MCP51 Serial ATA ... USB 1.1 'Open' Host Controller Driver ...
    (Linux-Kernel)
  • RE: XP box maintainance and lockdown
    ... download latest virus definitions ... Router Configuration ... to obtain protocol, local port, remote port, and IP address needed to ... disable 3rd-party cookies and/or set cookie policy according to ...
    (Security-Basics)
  • AHCI - remove probing of ata2
    ... On the Intel, I've connected an IDE HDD and a CD-RW, no problem. ... port is slow to respond, ... I'm lost in all the JMICRON configuration possibilities in the ... # ACPI Support ...
    (Linux-Kernel)