0

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;
 PortOpts.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IXANY | INPCK);
 // 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");
        close(fd);
        return 1;
    }
 } else {
    perror("While configuring port2");
    close(fd);
    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.

8
  • The obvious question is "What is the value of fd?" That is, did you check the return value from the open()? Why are you not checking the return value of tcgetattr()? For a simpler code example using cfmakeraw(), see stackoverflow.com/questions/12437593/… Commented Mar 4, 2013 at 1:29
  • @sawdust fd is 3 for this moment. Device file is opened just ok. I've read manual about cfmakeraw() but it will make 8N1 frame format. Sure thing it's not a big deal about how many stop bits there are when you have to transmit no more than 1 byte at a time, but it is fundamental. You were right. I've got the same error while getting serial port paramters. So this is because of there is no physical device? Commented Mar 4, 2013 at 1:38
  • If you are using a USB-RS232 adapter, then issue shell command ls /dev/ttyUSB*. Use that device name for open() instead of /dev/ttyS0. It is very rare for modern UARTs or USARTs to require two stop bits. I (and many others) use 1 stop bit for 115200 baud with zero or minimal intercharacter gaps without any issues. Typical reason for more than 1 stop bit is inaccurate baud rate generator. Commented Mar 4, 2013 at 1:51
  • @sawdust I don't have any adapters. I need to check my program for it is running ok (at least pre-transmition block). Thanks for the tip about stop bits. I'll try using 1 stop bit. Commented Mar 4, 2013 at 2:06
  • I've been writing drivers for decades, and do not see how you can use actual system calls with hardware that does not exist. The open() should have failed; that's a device driver that is too forgiving. If there is no device, then all system calls for I/O and device control have to be bypassed & replaced with simulated functions. Commented Mar 4, 2013 at 2:18

1 Answer 1

1

Can you run strace on the program; that will give more specifics of just where the IO error is occurring.

One thing to keep in mind - errno doesn't get reset, so the actual error could be from any system call before the perror.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.