Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 307
  • Last Modified:

serial access in linux

I've looked over previous quesitons regarding serial port access through linux, but didn't totally understand what was the best/easiest way to program on the ports.  I want to read in through COM1 and read/write through COM2.  I see open("/dev/ttyS0", O_RDWR).  I understand the first arguement, but I don't understand what the declared constansts are and through which library I'm supposed to include to access them.  Also, when I do have the read only port open, it will have to wait for data 24/7.  I don't know the best way to do that (is there a boolean that is changed on the event of buffer status change?) or even how to do that with the read() write() functions.  
0
Socr420
Asked:
Socr420
  • 2
  • 2
  • 2
  • +2
1 Solution
 
RobsonCommented:
Have a look at: http://www.tldp.org/HOWTO/Serial-Programming-HOWTO/index.html.
There's nothing wrong with waiting for data 24/7. The kernel puts your program to sleep so it doesn't consume CPU power until some datta arrives. If you want your program to do other things while waiting for data, you may use:

* multiple processes or multiple threads
* non-blocking read/write
* select or poll system calls

I suggest you to read some general UNIX programming book before to learn about all these techniques and decide which one is most suitable for you.

Robson.
0
 
Socr420Author Commented:
I've been to that site already.  I couldn't properly read in data and display it to screen.  Here is some code I'm trying to use to just display something caught from the serial port.
#include <stdio.h>


int main() {
        int fd;
        char inputString[20];
        char temp;
        int i;
        //inputString=(char *)malloc(sizeof(char)*120);
        inputString[19]='\0';
        printf("opening first comport\n");
        if((fd=open("/dev/ttyS0", 2))<0) exit(-1);
        read(fd, inputString, 19);
        printf("******\n");
        for(i=0; i<20; i++) {
                printf("%c", *(inputString+i));
        }
        printf("******\n");
        //how would I write to the port? write(fd, "a", 1)??
        printf("program was activated, and now closing");
        close(fd);
        return;
}
Sometimes I won't get anything, and at other times I'll get complete garbage.  I know what the data being sent in looks like, and it is nothing like what I receive. Hope you can help.  Thanks
0
 
RobsonCommented:
I think you should have a closer look at your serial port settings: parity, speed, flow control and suchlike. Manual for 'stty' command will tell you more. What is this device that you read from? What serial parameters does it operate at? AND DON'T FORGET TO CHECK ALL SYSTEM CALLS RESULTS! The garbage you mentioned could be random data from inptutString, when read failed, but you won't know that unless you check read() result.

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
kuganCommented:
Try This code , O_RDWR is basically a no defined in the header file, using a no 2 as you have done is not a good practice, because even if the no is wrong the compiler want give any error , but you will get run time error which is hard to debug

#include <stdio.h>
#include <fcntl.h>
int
main ()
{
  int fd;
  char *inputString;
  char temp;
  int i, error;

  inputString = (char *) malloc (sizeof (char) * 120);

  printf ("opening first comport\n");

  if ((fd = open ("/dev/ttyS0", O_RDWR)) < 0)
    {
      perror ("Opening");
      exit (-1);
    }

  if ((error = read (fd, inputString, 19)) < 0)
    {
      perror ("Reading ");
      exit (-2);
    }

  printf ("******\n");
  for (i = 0; i < 20; i++)
    {
      printf ("%c", *(inputString + i));
    }

  printf ("******\n");
  //how would I write to the port? write(fd, "a", 1)??
  if ((error = read (fd, inputString, 19) < 0))
    {
      perror ("Reading");
      exit (-3);
    }

  printf ("program was activated, and now closing");
  close (fd);

  return 1;
}
0
 
Socr420Author Commented:
I tried that code, but I seem to get locked up at the reading part.  It just sits there, and doesn't give any error.  I know there's input coming in because I connected a Tripmate GPS antenna to it.  I know every second the word "ASTRAL" is sent in at 4800 baud.  If I send the word "ASTRAL" back to it, it'll start sending all sorts of other data as well.  But I don't think I'm even sending correctly.  Is the cread option supposed to be on?  When I type "stty -F /dev/ttyS0" I see -cread is on, along with the other two defaults.
0
 
kuganCommented:
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>

#define USE_NO_FLOW 0
#define USE_FLOW_CTRL 1


void
fd_setup (int fd, int speed, int flow)
{
  struct termios t;


  if (fd < 0)
    {
      perror ("fd_setup");
      exit (-1);
    }

  if (tcgetattr (fd, &t) < 0)
    {
      perror ("tcgetattr");
      exit (-1);
    }

  cfmakeraw (&t);

  t.c_cflag &= ~CBAUD;
  t.c_cflag |= speed| CS8 | CLOCAL;
  t.c_oflag = 0;                /* turn off output processing */
  t.c_lflag = 0;                /* no local modes */

  if (flow)
    t.c_cflag |= CRTSCTS;
  else
    t.c_cflag &= ~CRTSCTS;

  if (tcsetattr (fd, TCSANOW, &t) < 0)
    {
      perror ("fd_setup : tcsetattr");
      exit (1);
    }
  return 1;
}

int
main ()
{
  int fd;
  char *inputString;
  char temp;
  int i, error;

  inputString = (char *) malloc (sizeof (char) * 120);

  printf ("opening first comport\n");

  if ((fd = open ("/dev/ttyS0", O_RDWR)) < 0)
    {
      perror ("Opening");
      exit (-1);
    }

  fd_setup(fd,B4800,USE_FLOW_CTRL);

  if ((error = read (fd, inputString, 19)) < 0)
    {
      perror ("Reading ");
      exit (-2);
    }

  printf ("******\n");
  for (i = 0; i < 20; i++)
    {
      printf ("%c", *(inputString + i));
    }



  printf ("program was activated, and now closing");
  close (fd);

  return 1;
}

by default if you open the /dev/ttyS0 the data will not be read until the input stream not terminated as far as i remember. and default baud is 9600 baud.

you first try " cat /dev/ttyS0" to see if you are getting the data and then set the termios structure properly and try, check baudtrate ,folwcontrol etc

I dont have a serial cable :-) to test it here

0
 
RonaldMundellCommented:
Hi

If you look under X you would see a section for documentation. Under there you would find 2 doc's containing how to write serial comms. this explains excactly what you need to do, where to select what Comms Port, etc... If this does not help, then EMAIL me and I will forward you the POSIX Serial Porgramming Manuel (an electronic copy). If I could upload it now, I would.

Ronald
0
 
jmcgOwnerCommented:
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Accept: Robson {http:#7162615}

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jmcg
EE Cleanup Volunteer
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 2
  • 2
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now