Problem accessing serial port (9600 7-E-1)

Posted on 2006-05-20
Medium Priority
Last Modified: 2012-05-05
I am writing a simple program which is intended to send short strings to a device i have attached to the serial port of my target machine. The simple program i have written seems to achieve this however the external device requires specific settings as follows.

9600 Baud, 7-bit data, 1 start bit, 1 stop bit, even parity.

After reading a number of samples off the web i decided on this code to set the relevant flags...

termio.c_cflag = B9600 | CS7 | PARENB | CLOCAL | CREAD;
tcflush(ttys0_fd, TCIFLUSH);
tcsetattr(ttys0_fd, TCSANOW, &termio);

I have tried every combination of c_flag settings that made sense from what i read but every time tcsetattr() is called with the specific settings the serial port seems to stop working all together and next time the program runs it cant even access the port.

When i let the program run with whatever default settings exist, i can send and receive strings no problem. What am i doing wrong? This has taken far longer than i had anticipated :(

Thanks in advance. Ill post the entire code if necessary.
Question by:HaL
  • 2
LVL 35

Accepted Solution

Duncan Roe earned 1000 total points
ID: 16728023
It's easier to do an stty -F {wanted device} {wanted characteristics} in the shell script before running the program.

If you really must do it programmatically:-

You should always read the current settings into your struct termios, and then modify the ones you care about. Also always use struct termios, not the old struct termio.

   struct termios termio;

   if (tcgetattr(ttys0_fd, &termio)) {perror("tcgetattr");exit(1);}

Use cfset[io]speed to set speeds:

   if (cfsetospeed(&termio, B9600)) {perror("cfsetospeed");exit(1);}
   if (cfsetispeed(&termio, B9600)) {perror("cfsetispeed");exit(1);}

Clear bits you don't want:

   termio.c_cflag &= ~(CSIZE | CSTOPB | CRTSCTS | PARODD);  

Set the bits you want:

   termio.c_cflag |= CS7 | PARENB | CLOCAL | CREAD;

(I added clearing of CRTSCTS hardware flow control).
After your tcsetattr(), you should do a tcgetattr() to another struct termios and compare it for equality with the first one, to ensure all the facilities you requested were set.


Author Comment

ID: 16728430
Thanks a lot for the example. This is exactly what i was looking for and it works a treat. It seems that serial devices are a little more touchy than i had previously though, at least in Linux anyway.

I was wondering why cfsetospeed() is used to set the speed instead of adding the B9600 flag directly to the c_cflag property. Perhaps to prevent multiple speeds being applied?

Thanks again, the points are yours.
LVL 35

Expert Comment

by:Duncan Roe
ID: 16728481
Thanks Hal. To answer your question - in "man termios" see
"(POSIX  says  that  the  baud  speed  is stored in the termios structure without specifying where precisely, and provides cfgetispeed() and cfsetispeed() for getting at it. Some systems use bits selected by CBAUD in c_cflag, other systems use separate fields, e.g.  sg_ispeed and sg_ospeed.)"

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say 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…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Screencast - Getting to Know the Pipeline
Suggested Courses

850 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