Serial port reading data problem

New result:

Code list:
int main(int argc, char *argv[])
{
int nsIMU = open("/dev/ser1", O_RDWR);
termios term;
tcgetattr(nsIMU, &term);
cfsetispeed(&term, 57600); //input and output baudrate
cfsetospeed(&term, 57600);
term.c_cflag = CS8 | CLOCAL | CREAD;
tcsetattr(nsIMU, TCSANOW, &term);

char szBuffer[4096];
char bufAH440[] = {0x55,0x55,0x47,0x50,0x02,0x41,0x30,0x94,0x87};	// NAV440 poll A0
char buf0Hz[] 	= {0x55,0x55,0x53,0x46,0x05,0x01,0x00,0x01,0x00,0x00,0x40,0x81};

tcflush(nsIMU, TCIOFLUSH);
usleep(500000);
::write(nsIMU, buf0Hz, 12);
usleep(15000);

// Poll 'A0'
int nWrite = ::write(nsIMU, bufAH440, 9);
if(nWrite!=9)
	cout<<"Write operation error"<<endl;
usleep(500000);

while(1)
{
	static int errCnt = 0;

// double t1 = ::GetTime();
usleep(20000);
int nRead = read(nsIMU, szBuffer, 50);
// tcflush(nsIMU, TCIFLUSH);
if (nRead>0)
{
cout<<"Bytes rcved: “<<nRead<<endl;
for (int i=0;i<nRead;i++)
{
printf(”%02x ", (unsigned char)szBuffer[i]);
}
cout<<endl;
if(nRead!=37)
errCnt++;
cout<<"error packets: "<<errCnt<<endl;
}
else
cout<<“No packets”<<endl;

::write(nsIMU, bufAH440, 9);


}
return EXIT_SUCCESS;

}

I attached the outcome in the annex. The current problem is after 69 times of error packets, the following requested packets all arrive correctly. If i paused the program, and then continue, then after 69 or 68 times of period, the requested packets will again return to the correct streams. No ideas on the hardware side, or my software side. Look forward to suggestions.

Eric

For the read operation, if the serial is set to blocking, then when there is no data available in the buffer of the serial port, then the program get stuck in the read operation?

And what are the differences btw read 1024 bytes and 50 bytes? and time consumption of each, how roughly can be calculated?

And if in the non-block status, the read will read as much data as possible if there are data in the buffer?

Thanks,
Eric

Eric,

Yes. That’s the definition of blocking.

None. The only thing the 3rd parameter does is tell read how big your receiving buffer is. It has no effect on how long read waits before it returns data. When you call read if there is 1 byte or 1024 bytes in the serial buffer it will return right away with data. The only difference at that point is if you pass a value of 50 and there are 1024 bytes waiting you’ll only get 50 of them. In other words the 3rd parameter DOES NOT tell read to wait until there are X number of bytes before returning.

Nope. Non-blocking works exactly like blocking in terms of amount of data returned. It won’t return any more than you request in the 3rd parameter. The primary difference in the non-blocking case is that the read call ALWAYS returns right away (with 0 bytes if no data is available) in non-blocking mode.

BTW, looking at your latest data you have a minor bug in your program regarding the 1st packet. You send 2 packets to the device before you do an initial read. This is why your 1st reply is 47 bytes long, the 37 byte reply plus I assume 10 bytes from the initialization packet you sent 1st. This causes you to call the 1st received packet an error when it’s not.

Looking after that it appears that something else is going on. Your next bunch of packets are all not fully received in 20 ms (you only get 8 out of 37 bytes). That leaves 29 bytes arriving late. 29*8=232 bits. 232 bits divided by the 57400 baud rate equals .004 or 4 ms over run.

At this point only 2 things can explain that much over run:

  1. The hardware device isn’t always making the 20 ms reply it claims. You have to put a scope on the serial line (sending and receiving) and prove that the card is not getting the data back on the line within the promised 20 ms interval.

  2. Something else in your QNX machine is keeping devc-ser8250 (serial driver) from running. The driver normally runs at priority 24. So it would have to be something at a higher priority. How exactly are you running these tests? Are they done directly on the QNX machine or via Eclipse? Are you running in Photon or in a native terminal? Is there any other application using another serial port while you are doing these tests etc? Ideally you should be doing these tests in a native QNX terminal without Eclipse.

Tim