-   Programming (
-   -   Can't set serial port configuration in Linux in C (

sevs 03-03-2013 07:58 PM

Can't set serial port configuration in Linux in C
I have writen some Linux program to comunicate my device. I have "same" my program for Windows ("same" because of it's same logic).
I'm using 8N2 data frame format @ 9600 bps, with neither software (XOn/XOff) nor hardware (RTS/CTS) flow control. I don't use DTR, DCD, RI, DSR pins of RS-232 9-pin D-sub. I use only RX and TX pins to communicate with my device.
In Linux I have this part of code:


struct termios PortOpts, result;
 int fd; /* File descriptor for the port */
/* Configure Port */
 tcgetattr(fd, &PortOpts);
 // BaudRate - 9600
 cfsetispeed(&PortOpts, B9600);
 cfsetospeed(&PortOpts, B9600);
 // enable reciever and set local mode, frame format - 8N2, no H/W flow control
 PortOpts.c_cflag &= (~(CLOCAL | CREAD | CSIZE | CSTOPB));
 PortOpts.c_cflag |= ((CLOCAL | CREAD | CS8 | CSTOPB) & (~PARENB));
 PortOpts.c_cflag &= (~CRTSCTS);
// PortOpts.c_cflag &= ~PARENB
// PortOpts.c_cflag |= CSTOPB
// PortOpts.c_cflag &= ~CSIZE;
// PortOpts.c_cflag |= CS8;
 // no parity check, no software flow control on input
 PortOpts.c_iflag |= IGNPAR;
 // raw data input mode
 PortOpts.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
 // raw data output
 PortOpts.c_oflag &= ~OPOST;
 // setting timeouts
 PortOpts.c_cc[VMIN] = 1; // minimum number of chars to read in noncanonical (raw mode)
 PortOpts.c_cc[VTIME] = 5; // time in deciseconds to wait for data in noncanonical mode (raw mode)

 if (tcsetattr(fd, TCSANOW, &PortOpts) ==  0) {
    tcgetattr(fd, &result);
    if ( (result.c_cflag != PortOpts.c_cflag) ||
        (result.c_oflag != PortOpts.c_oflag) ||
        (result.c_iflag != PortOpts.c_iflag) ||
        (result.c_cc[VMIN] != PortOpts.c_cc[VMIN]) ||
        (result.c_cc[VTIME] != PortOpts.c_cc[VTIME]) ) {
        perror("While configuring port1");
        return 1;
 } else {
    perror("While configuring port2");
    return 1;

File descriptor 'fd' is for '/dev/ttyS0' device.
I get that message: **While configuring port2: Input/output error**
I have a laptop, though I don't have any serial ports except for USB. Is this a reason?
I run program as 'root'.

Sorry for my broken English.

DiBosco 03-03-2013 08:03 PM

Are you saying you do not have an old fashioned serial port but a USB virtualcom port (VCP) or (CDC class as it's sometimes called)?

If so, that would be:

/dev/ttyUSBx or

Where x is a number.

If you search in dev for those files you will hopefully find one. You shouldn't run as root though really. Make your user member of dialout function and I think that will do you.

sevs 03-03-2013 08:10 PM

Yes. I don't have the hardware serial port. But I've got the device in my /dev filesystem named /dev/ttyS0 with major and minor numbers 4 and 64 respectively.
I've got only /dev/tty, /dev/tty[0-63], /dev/ttyS[0-3].
I don't have USB virtualcom at hand riht now.
But I do need to test the program in Linux.
I could try pointing to some terminal but I'm afraid of its unforseen behaviour.

UPD: I've added bsome more code (error checking after I retrieve serial port parameters):

if (tcgetattr(fd, &PortOpts) < 0) {
    perror("While getting serial port parameters");
    return 1;

And the error is about here. I think this is becuase of physical device absence.

DiBosco 03-03-2013 09:14 PM

Yes, I would think the error is because you have no actual com port. Using Cutecom, I can, apparently, open the non-existant /dev/ttyS0 on my laptop, but I get errors on the command line.

You can buy FTDI based cables that have a 9 way D connector on one end and a USB connector on the other. That will give you a serial port, but called /dev/ttyUSBx and it will work perfectly. They're not expensive, only about 15.

DiBosco 03-03-2013 09:15 PM

theNbomr 03-04-2013 01:24 PM

Use a terminal emulator such as minicom or C-Kermit to figure out how Linux has mapped device names to your hardware. Loop pins 2 & 3 on the serial port to establish that characters you type are displayed on the terminal emulator.
Once you've established the proper naming, use that in your code. Also, verify that you have permission to perform the operations your code performs.

'/dev/ttyWhatever' is not a file descriptor; it is a device name. You haven't shown any code that uses the device name to open the device and create a file descriptor. Have you checked the return value from the open() call?

--- rod.

suicidaleggroll 03-04-2013 01:29 PM


Originally Posted by sevs (Post 4903946)
Yes. I don't have the hardware serial port.

You can't configure a serial port that doesn't exist. Just run to your neighborhood electronics store and pick up a USB to RS232/Serial/DB9 adapter. When you plug it in, you should see a new device called /dev/ttyUSB0, which you can then configure and use in your program.

All times are GMT -5. The time now is 03:36 PM.