We help IT Professionals succeed at work.

Read/Write to Linux serial port using C or C++

mag062397
mag062397 asked
on
Medium Priority
1,199 Views
Last Modified: 2013-12-26
OS Version: Red Hat Linux release 3.0.3
Language: GNU gcc 2.7.2-2 or g++ 2.7.2-2

I need an example of how to write and read characters to the /dev/cua0 device (COM1) in Linux.  I need to communicate at a baud rate of 1200, 8 data bits, 1 stop bit, and no parity.  (1200,N,8,1).

I have tried the following code fragement:
--------------------
 if ((serial_fd = open("/dev/cua0",O_RDWR))==-1) {
    printf("Error opening /dev/cua0\n");
    return -1;
  }

  buf[0] = (char)1;
  buf[1] = (char)24;
  buf[2] = (char)230;
  i = write(serial_fd,buf,3);
  printf("wrote %d bytes\n", i);

  i = read(serial_fd, buf, 4);
  printf("read %d bytes, errno=%d\n", i,errno);      
-----------------

It writes the characters out.  I put a tester (on the port) with LEDs that flickers when the program sends characters to the port.  However I don't know how to set the port to no parity, 8 data bits, and 1 stop bit.  I was able to use the setserial command to set the baud rate.  

Does anyone have an example on how to do this?
It can be in either C or C++.
Comment
Watch Question

Commented:
Check the termios(3) functions.  The ones you want are tcgetattr() [get current settings] and tcsetattr() [change settings].  Your code would look like this:
------------------------------------------------------
struct termios old_settings;
struct termios new_settings;

tcgetattr( serial_fd, &old_settings );
new_settings = old_settings;
cfsetispeed( &new_settings, B1200 );
cfsetospeed( &new_settings, B1200 );
new_settings.c_cflag &= ~(PARENB | CSTOPB);
tcsetattr( serial_fd, &new_settings );
-----------------------------------------------
Cfset[io]speed() are convenience functions that set the appropriate bits in the terminal control structure; you could use bitwise ANDs and ORs to accomplish the same thing.  In the next to last line, I clear the Parity-Enable and 2-Stop-Bits flags.  Incidentally, the reason I have two termios structures (old_settings and new_settings) is that it's polite to restore the terminal to the state you found it when your program exits.

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
dhm

Commented:
Whoops, forgot to set 8-bit mode...add these lines before the tcsetattr():

new_settings.c_cflag &= ~CSIZE;
new_settings.c_cflag |= CS8;
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.