Problem in using readcond for reading from /dev/ser

Hi,

I’m a newbie in QNX (I’m using 6.2) and trying to figure out how to work properly with serial ports. I’m using readcond to read data and found that if there is no data to recieve, the readcond timeout never fires somehow. I think it is because of the not RAW usage of com port, but I can’t figure out how to do in a right way using termios structure

Port initialization

	if ((m_port_handle = open(m_dev_port.c_str(), 
										O_RDWR))<0) {
	exception_message<<"Can`t open com port "<<m_dev_port<<" : "<<strerror(errno);
	 throw comport_exception(exception_message.str());
	 }
<skip>
    termios_param.c_lflag &= ~( ECHO|ECHOE|ECHOK|ECHOKE|ECHOCTL|ECHONL|ICANON|ISIG);
	termios_param.c_cflag &= ~CLOCAL;
	termios_param.c_iflag &= ~IMAXBEL;
	termios_param.c_oflag &= ~ONLCR;
<skip>

Reading data


  while(bytes_readed_summary<bytes_count) {
    bytes_readed = readcond(m_port_handle,
                            &recived_data[0],
                            bytes_count,
                            bytes_count,
                            0,
                            6); //expire if 6*1/10 sec (600 mS)

    	if (bytes_readed<0) {
 		exception_message<<"Can`t  read from "<<m_dev_port<<" : "<<strerror(errno);
		throw comport_exception(exception_message.str());
    	};
       if (bytes_readed==0) break;

         bytes_readed_summary+=bytes_readed;
         iter_on_received_data=recived_data.begin();
         advance(iter_on_received_data, bytes_readed);

         buffer_to_recieve.insert(buffer_to_recieve.end(), recived_data.begin() , iter_on_received_data);
    };

Thanks in advance

Korav,

What is the value of bytes_count?

If it is 0 then you end up with an undefined setting to readcond (bytes=0, time=0, timeout=t is undefined).

Tim

Thanks for the quick answer Tim, no, the value of bytes_count is not 0.
This value is checked before the function called. In addition, the while loop condition wont be true in this case.

Korav,

I just read your initial comment again.

You mentioned you are not opening the port in RAW mode. Therefore according to the doc’s on readcond the bytes/time arguments are going to be
ignored. This is likely your problem.

Personally when I read data from a serial port/Ethernet socket I use the ‘select’ statement to handle the reading of data with a timeout. Bypasses all the readcond/termios issues and allows for reading from multiple sources of data (multiple serial ports/Ethernet sockets).

Tim

An alternative is to create a thread, use read in the thread. If you need to sync with the main thread you can use a condvar or message passing.

But readcond() does work nicely if you open the port in raw mode.

Thanks a lot for your answers!

Yes, I’ve read it in help, and my initial idea was that the problem with timeout was because the port is not in raw mode.

Could you kindly help me and suggest, how to get the port in raw mode programmatically using some combination of flags of termios structure, for example?

cfmakeraw()

Thanks a lot for your answer, maschoen! Yes, I had tried it but I thought that as I modifying flags for data bits, stop bits, parity check etc after cfmakeraw() I’m resetting it somehow.

The actual problem was in my assumption that readcond returns -1 when it was interrupted by timeout but actually it returns 0. That is why the while loop, that is shown on my first post, was endless. When I attached my process using GDB I saw that the thread blocked on MsgRecieve in readcond, so, I decided that readcond never returns. So, the result loop for reading data is


  while(bytes_read_summary<bytes_count) {

    bytes_read = readcond(m_port_handle,
                            &recived_data[0],
                            bytes_count,
                            bytes_count,
                            0, 
                            10); //expire if 10*1/10 sec (1 S)

    	if (bytes_read<0) {
 		exception_message<<"Can`t  read from "<<m_dev_port<<" : "<<strerror(errno);
		throw comport_exception(exception_message.str());
    	};
       if (bytes_read==0) {
 		exception_message<<"Empty response from "<<m_dev_port;
		throw comport_exception(exception_message.str());
    	};

         bytes_read_summary+=bytes_read;
         iter_on_received_data=recived_data.begin();
         advance(iter_on_received_data, bytes_read);

	     buffer_to_recieve.insert(buffer_to_recieve.end(), recived_data.begin() , iter_on_received_data);
		usleep(1000); //sleep for 1mS until new data arrives
    };

The problem is solved, thanks a lot for your time!