Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

serial access in linux

Posted on 2002-07-17
9
Medium Priority
?
305 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 400 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
Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

 

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
 

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 Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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 fix the unknown display problem in Linux Mint operating system. After installing the OS if you see Display monitor is not recognized then we can install "MESA" utilities to fix this problem or we can install additio…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …

604 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