0

I have written a program in c for reading and writing serial port.But the problem is I am using while loop and it is continuously sending the command over the serial port.

  1. I want to write some command on serial port
  2. wait for answer
  3. write another command
  4. wait for some answer and so on

My code goes like this:-

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <errno.h>
#include <time.h>

 int main()

  {   
   printf("\n");
   printf("Please wait till serial Port is  being Initialized .... \n");
   sleep(2);
   printf("\n................. Initializing ................\n");
   sleep(2);
   printf("\n");
   printf("\n\n");
   static int fd = 0;
       int len;
       char res[100];
       char s[100] = " Hellow World";


     struct termios options;

    //==================================================================
    //                  hard coaded port ttyO3
    //==================================================================

      fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); 
          fcntl(fd, F_SETFL, O_NONBLOCK);

     //==================================================================
     //                             Error Handling
     //==================================================================

            if (fd < 0)
      {
      printf("Serial open error %d %s\n", errno, strerror(errno));
          }
      printf("\n");

    printf("\n==================================================\n");

   //==================================================================
   //                 Get the current options for the port...
   //==================================================================

    tcgetattr(fd, &options);


         //==================================================================
    //                Set the baud rates to 115200...
   //==================================================================


    cfsetispeed(&options, B115200);
    cfsetospeed(&options, B115200);

    //=================================================================
   // Enable the receiver and set local mode..
  //==================================================================

    options.c_cflag |= (CLOCAL | CREAD);

//==================================================================    
// Set the new options for the port...
//==================================================================

     tcsetattr(fd, TCSANOW,&options);

      while(1)
        {  



      write(fd,s,strlen((char*)s));   
      sleep(1);

      len = read(fd,res,100);  
      if (len < 0)
       {   
         if (errno == EAGAIN)
         {         
               continue;
         }
         else
         { 
             printf("read error %d %s\n", errno, strerror(errno));
         } 
       }
     else
      {                   
        res[len < 100 ? len:100] ='\0';
        printf("read %d chars: %s\n",len, res);
      } 
    }
     close(fd);
    } 

where am I getting wrong.

Thanks and Regards

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621

2 Answers2

1

It looks like the file descriptor is opened as non-blocking (fcntl(fd, F_SETFL, O_NONBLOCK);). You must have some blocking operation if you want to wait for data to be read.

You can make the file descriptor blocking, or use some asynchronous manager like select.

eyalm
  • 3,366
  • 19
  • 21
1

Since you make your file descriptor non-blocking (twice), you have to as the system to wait between the steps. A common way to do this is the select system call, which you can use to wait until there is something to read from the file descriptor.

Can be done something like this:

write(...);

fd_set poll_set;
FD_ZERO(&poll_set);
FD_SET(fd, &poll_set);

/* Wait, with no timeout, for something to be readable */
int rc = select(fd + 1, &poll_set, NULL, NULL, NULL);
if (rc == -1)
{
    perror("select");
}
else
{
    /* Continue to next step, where you read */
}

Also note that the read-calls may actually not receive the complete messages in the first attempt. You may have to read multiple times to get the complete message. If your messages are of a fixed size, then read in a loop while decreasing the amount of bytes to read until you have received the complete message. If your message have a end-of-message marker, then read byte by byte until you receive it. If your messages contain a header with the message size, then use the first fixed-size read method twice, once to get the header and once to get the data.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621