Solved

serial access in linux

Posted on 2002-07-17
9
294 Views
Last Modified: 2006-11-17
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
Comment
Question by:Socr420
  • 2
  • 2
  • 2
  • +2
9 Comments
 
LVL 4

Expert Comment

by:Robson
ID: 7161671
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
 

Author Comment

by:Socr420
ID: 7161801
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
 
LVL 4

Accepted Solution

by:
Robson earned 100 total points
ID: 7162615
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
 

Expert Comment

by:kugan
ID: 7163942
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

Author Comment

by:Socr420
ID: 7165537
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
 

Expert Comment

by:kugan
ID: 7166121
#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
 

Expert Comment

by:RonaldMundell
ID: 7167518
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
 
LVL 20

Expert Comment

by:jmcg
ID: 9925610
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

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Have you ever been frustrated by having to click seven times in order to retrieve a small bit of information from the web, always the same seven clicks, scrolling down and down until you reach your target? When you know the benefits of the command l…
The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now