Help needed for reading serial port under SCO 3.2

Help needed for reading serial port under SCO 3.2

Post by Jeff Dicks » Sat, 22 Jul 1995 04:00:00




>We want to read raw data from a serial port on a system with SCO-Unix 3.2
>and wrote the short program in the appendix for testing. The special
>application needs to read 43 bytes, containing ascii chars and hex
>values. We read some bytes, but rarely all 43. It looks like there are
>whole blocks of bytes missing, at various places with no appearant
>regularity.

The reason this is occurring is that you are opening the tty for non blocking
and not all 43 characters are immediately available.  So instead of waiting
for those characters to be received (blocking) however many available are read.
To handle this condition properly you would need to note the value returned
by read and if fewer characters were received than expected - re-issue. Some-
thing like this:

    read_bytes = 0;
    read_cnt = 100;
    do
    {
        if ((rv = read(pipe_handle_w, &buffer[read_bytes], read_cnt)) > 0) {
            read_bytes += rv;
            read_cnt -= rv;
        }
    } while (read_cnt != 0);    
    printf ("read_bytes: %d\n", read_bytes);

Another thing to consider is that when a tty is initially opened it is in
canonical mode. Here input characters are assembled into lines meaning that
a newline character must be received before the characters that make it up
can be read. Also, certain signicance is given to certain characters for
line editing purposes.

If this is not what you want then this mode can be turned off. I strongly
urge you read up on terminal I/O, because once you do this then it's possible
to have the terminal I/O driver handle what I started out saying you had to
handle.

Jeff S.*son

 
 
 

Help needed for reading serial port under SCO 3.2

Post by Hans Kra » Sat, 22 Jul 1995 04:00:00


We want to read raw data from a serial port on a system with SCO-Unix 3.2
and wrote the short program in the appendix for testing. The special
application needs to read 43 bytes, containing ascii chars and hex
values. We read some bytes, but rarely all 43. It looks like there are
whole blocks of bytes missing, at various places with no appearant
regularity.

The mode of the device '/dev/tty1a' frequetly changes from 666 to 700
and we must reset it for accesssing.

One last: when we are writing to the serial device (same flags) how do we
prevent the echoing of data to the screen?

Any help appreciated, we are at the end of our wits.

        MfG., Hans
--

                Tel:   +43 1 60171 7217
                Fax:   +43 1 60171 7202

-----------------%x-----------------%x-----------------%x----------------

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>

int main (int  argc,
          char **argv)
{
  int            idx;
  int            mode;
  int            pipe_handle_w;
  int            read_bytes;
  int            b_idx;
  char           buffer[100];
  char           ack_code[100];
  struct termios term;

  printf ("SERTEST: *** START\n");

  /* open serial device */
  mode = O_RDWR | O_NONBLOCK;
  if ((pipe_handle_w = open ("/dev/tty1a", mode)) == (-1))
  {
     printf ("SERTEST: Fehler '%d' bei oeffnen der pipe\n", errno);
     exit (0);
  }    

  /* Attribute von 0 einlesen (0=STDIN) */
  if (ioctl (pipe_handle_w, TCGETA, &term) == (-1))
  {
    printf("SERTEST: Fehler in Funktion ioctl(1)\n");
    close (pipe_handle_w);    
    exit (0);
  }

  term.c_iflag = IGNBRK | PARMRK;
  term.c_oflag = 0;
  term.c_cflag = B9600 | PARENB | PARODD | CLOCAL | CS7 | CREAD;
  term.c_lflag = 0;
  term.c_cc[4] = 10;
  term.c_cc[5] = 1;

  if (ioctl (pipe_handle_w, TCSETA, &term) == (-1))
  {
    printf("SERTEST: Fehler in Funktion ioctl(2)\n");
    close (pipe_handle_w);    
    exit (0);
  }

  idx = 0;
  while (idx < 1000000)     /* ashamed of it, but for a trial ... */
  {
    idx++;
    if ((read_bytes = read  (pipe_handle_w, buffer, 100)) > 0)
    {

      printf ("read_bytes: %d\n", read_bytes);

      for (b_idx=0; b_idx < read_bytes; b_idx++)
      {
        if ((buffer[b_idx] >= 0x20) &&
            (buffer[b_idx] <  0x7F))
        {
          printf ("%c|", buffer[b_idx]);
        }
        else
        {
          printf ("0x%02x ", (buffer[b_idx] & 0xFF));
        }
        fflush (stdout);
      }
    }
  }

  /* pipe schliessen */
  close (pipe_handle_w);

  printf("SERTEST: *** ENDE\n");
  exit (0);

Quote:}

-----------------%x-----------------%x-----------------%x----------------