# [Solved] serial port buffer and configuration issue

## diefast

Hello,

I have used gentoo 2.6.14 without any problems on the MB serial port, USB-Serial dongle, and Serial expansion PCI cards. I have upgraded to 2.6.19 and have a fit with my serial port. I cannot figure out how to initialize the port. I am trying to open read and write descriptors separate such that the read descriptor blocks on read. I am including a sample code I have been playing with. I can read just fine, but my write ends up with an error number 11. If you have some thoughts about what changes in the serial port configuration happened between 2.6.14 and 2.6.19, please help. I have looked over my configuration and cannot pin the issue. I have tested my sample with USB dongles, MB port, and the PCI 4 port cards. This is also not a machine specific issue. I have tested my old code on gentoo 2.6.14, 2.6.12 and kubuntu 2.6.12. Current 2.6.19 gentoo and upgraded kubuntu result in the same errors. 

If you have a pointer or and advice (or both) please pass such. 

here is a sample code for the port io trial

```

#include    <termios.h>

#include    <stdio.h>

#include   <errno.h>

#include    <unistd.h>

#include    <fcntl.h>

#include    <sys/signal.h>

#include    <sys/types.h>

int main(int Parm_Count, char *Parms[])

{

   /* file descriptors */

   int    read_port_desc, write_port_desc;

   char   serial_device_file[] = "/dev/ttyUSB1";

   int   read_flags =    O_RDONLY | O_SYNC | O_NOCTTY;

   int   write_flags =    O_WRONLY | O_SYNC | O_NOCTTY; 

   struct termios read_port_options, write_port_options, old_port_options;

   read_port_desc  = open(serial_device_file, write_flags);

   write_port_desc = open(serial_device_file, write_flags);

   if(read_port_desc > 0 && write_port_desc > 0)

   {

      printf("set write to non-blocking, and read to blocking io\n");

      fcntl(write_port_desc, F_SETFL, 0);

      fcntl(write_port_desc, F_SETFL, FNDELAY);

      //fcntl(read_port_desc, F_SETFL, 0);

   

      printf("get the current options for the port\n");

      tcgetattr(read_port_desc, &old_port_options); 

      printf("setup the individual read & write port options\n");

      read_port_options.c_cflag = write_port_options.c_cflag = B38400 | CRTSCTS | CS8 | CLOCAL | CREAD;

      read_port_options.c_iflag = write_port_options.c_iflag = IGNPAR;

      read_port_options.c_oflag = write_port_options.c_oflag = 0;

   

      printf("set input mode (non-canonical, no echo,...)\n");

      read_port_options.c_lflag = write_port_options.c_lflag = 0;

      printf("inter-character timer unused\n");

      read_port_options.c_cc[VTIME] = write_port_options.c_cc[VTIME]    = 0;   

      printf("blocking read until 1 chars received\n");

      read_port_options.c_cc[VMIN]     = 1;  

      printf("flush the input & output on the serial buffer\n");

      tcflush(write_port_desc, TCIOFLUSH);

      tcflush(read_port_desc , TCIOFLUSH);

      printf("set the new options for the write and read ports\n");

      tcsetattr(write_port_desc, TCSANOW, &write_port_options); 

      tcsetattr(read_port_desc, TCSANOW, &read_port_options); 

   }

   char    message[] = { 0x01, 0x00, 0x78, 0xF0, 0x7E, 0x8E };

   char    string[1000];

   int   length = 0;

   int   bytes_written = 0;

   while(1)

   {

      bytes_written = write(write_port_desc, message, 6);

      printf("Bytes written is %d\n", bytes_written);

      if(bytes_written<0)

      {

         printf("serial port write error %d %s\n", errno, strerror(errno));

      }

      usleep(1000000);

   }

   length = read(read_port_desc, &string, 1000);

   printf("Bytes read is %d\n", length);

   close(read_port_desc);

   close(write_port_desc);

   return 0;

} 

```

here is the output dump

```

localhost serial_tester # gcc  -c serial_tester.c  && gcc serial_tester.o -o example && ./example

set write to non-blocking, and read to blocking io

get the current options for the port

setup the individual read & write port options

set input mode (non-canonical, no echo,...)

inter-character timer unused

blocking read until 1 chars received

flush the input & output on the serial buffer

set the new options for the write and read ports

Bytes written is 6

Bytes written is 6

Bytes written is -1

serial port write error 11 Resource temporarily unavailable

Bytes written is -1

serial port write error 11 Resource temporarily unavailable

Bytes written is -1

serial port write error 11 Resource temporarily unavailable

```

I stopped the program with the all mighty ctrl-c. Otherwise error 11 keeps on coming.

Thanks again and please do helpLast edited by diefast on Thu Apr 05, 2007 6:16 am; edited 1 time in total

----------

## diefast

I have stumbled on a solution. If I configure my file descriptors such

```

      /* set write to non-blocking, and read to blocking io */

      fcntl(read_port_desc,  F_SETFL, 0);

      fcntl(write_port_desc, F_SETFL, FNDELAY);

      tcgetattr(read_port_desc, &old_port_options); 

      cfsetispeed(&read_port_options,  B38400);

      cfsetospeed(&write_port_options, B38400);

      read_port_options.c_cflag  |= B38400 | CRTSCTS | CS8 | CLOCAL | CREAD;

      read_port_options.c_cflag  &= ~PARENB;

      read_port_options.c_cflag  &= ~CSTOPB;

      read_port_options.c_cflag  &= ~CSIZE;

      read_port_options.c_cflag  |= CS8;

      read_port_options.c_cflag  &= ~CRTSCTS;

      write_port_options.c_cflag |= B38400 | CRTSCTS | CS8 | CLOCAL;

      write_port_options.c_cflag &= ~PARENB;

      write_port_options.c_cflag &= ~CSTOPB;

      write_port_options.c_cflag &= ~CSIZE;

      write_port_options.c_cflag |= CS8;

      write_port_options.c_cflag &= ~CRTSCTS;

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

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

      read_port_options.c_iflag  |= IGNPAR;

      write_port_options.c_iflag |= IGNPAR;

      read_port_options.c_oflag  &= ~OPOST;

      write_port_options.c_oflag &= ~OPOST;

   

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

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

      read_port_options.c_cc[VTIME] = write_port_options.c_cc[VTIME]    = 0;   

      read_port_options.c_cc[VMIN]     = 1;  

      tcflush(write_port_desc, TCIOFLUSH);

      tcflush(read_port_desc , TCIOFLUSH);

      tcsetattr(write_port_desc, TCSANOW, &write_port_options); 

      tcsetattr(read_port_desc, TCSANOW, &read_port_options); 

```

Everything works fine. I believe that the driver difference is in CRTSCTS. I have played with a variety of configurations, and CRTSCTS makes big difference. I am not sure why the code will work with 2.6.14, 2.6.15 but not with 2.6.19 kernels, unless I disable CRTSCTS.

RK

----------

