Are serial port settings permanent in Linux?

652 Views Asked by At

I have two programs to read from serial port, some device is connected at the other end. First program is written using Qt framework and it uses QextSerialPort to communicate with serial. Second program is written in pure C.

Problem is like this:

Right after system boot, pure C program has a problem with reading data from serial, I know that it sends data properly because device reacts for data, although pselect (that is monitoring serial_fd) never returns with serial_fd to read data from device.

When I start second program (written in Qt) it is sending and receiving data from device right away, no problem.

What is more, after I start Qt program, and then pure C program, pure C is suddenly working flawlessly, until I reboot system again. So it looks like program written in Qt changes some settings of serial port permanently during initialization, is this possible?

Below is snippet of code from Qt program that initializes serial port:

if (rs232->open(QIODevice::ReadWrite)) {
    rs232->setBaudRate(BAUD38400);
    rs232->setFlowControl(FLOW_OFF);
    rs232->setParity(PAR_NONE);
    rs232->setDataBits(DATA_8);
    rs232->setStopBits(STOP_1);
    connect(rs232, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
} else {
    qDebug() << "Rs232::rs232Connect OPEN PORT FAILURE";
    exit(1);
}

And this is from pure C program:

fd = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY);

if (fd == -1) {
/*
* Could not open the port.
*/
    error_exit(ERROR,"open_port: Unable to open /dev/ttyAMA0");
}
else
    fcntl(fd, F_SETFL, 0);

/*
 * Get the current options for the port...
 */

tcgetattr(fd, &options);

/*
 * Set the baud rates to 19200...
 */

cfsetispeed(&options, B38400);
cfsetospeed(&options, B38400);

/*
 * Enable the receiver and set local mode...
 */

options.c_cflag |= (CLOCAL | CREAD);

options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;

/*
 * Set the new options for the port...
 */

tcsetattr(fd, TCSANOW, &options);

Is there something missing or what ?

best regards Marek

2

There are 2 best solutions below

0
On

I'm grasping at straws here, but before doing anything else, I would suggest connecting another terminal to the other side and see if anything is happening at all. Your problem might be the fact you're not setting a flow control mode in the C application, try

options.c_cflag &= ~CRTSCTS;

If it still doesn't work, have a look at the accepted answer here; I've used the code a couple of times in the past and never had any problems with serial comms.

0
On

I know the question is old, but still there is no answer to the original question in the title.

So, yes, serial port settings are persistent in Linux in the sense that settings done to the port from one process may be visible to another process, even if the first process is ended already.

The settings are reset during system boot process.

Also, there is a special command line utility to query and set serial port settings: stty.

E.g., to query serial port settings, you may use:

stty -F /dev/ttyS0

which might be useful in your case to compare serial port settings after running both applications and find the difference that make the second application work.