Skip navigation.
Home
The QNX Community Portal

View topic - Serial port reading data problem

Serial port reading data problem

For discussion of realtime and/or embedded programming.

Postby juanplacco » Wed Apr 08, 2009 4:29 pm

So i don't think the status of the serial port may get changed during the execution of my program.


This happened to me once. As I remember it was the ohpaged flag. It did not happen with a P3 which run the application some time ago... but later, the hardware was replaced by a P4 and this crazy flag began to change from time to time. Really never knew why, but it did. We changed the application to set this flag before each write, and the application did not fail anymore.

But ok. This is not necessarily the case. I only suggest that you check this, to rule out a potential problem.

Regards,
JM
juanplacco
Senior Member
 
Posts: 318
Joined: Wed May 17, 2006 2:30 pm

Postby Ericxx » Wed Apr 08, 2009 5:07 pm

Tim wrote:Eric,
What your read thread has to expect is that it's not going to get 37 bytes at a time. It's going to get them sometimes 1 at a time and sometimes 2 at a time, sometimes 36 at a time etc. Your code has to deal with getting fewer bytes than expected and put together the multiple strings into one 37 byte packet.

Tim


Thanks so much for your analysis. Yes, i could make up a whole packet after several read operations. But our application requires to have a complete packet every 20ms. And the hardware itself claimed to be able to respond within 20ms. So after each request packet, after 20ms, the read operation should be able to retrieve 37 bytes data in the buffer. And i will check with the flag configuration as JM said. Thanks again.

Eric
Ericxx
Senior Member
 
Posts: 158
Joined: Mon Jun 09, 2008 1:38 pm

Postby Tim » Wed Apr 08, 2009 5:58 pm

Eric,

If the hardware claims it responds in 20 ms you better plan on leaving a couple extra ms to read the data. In other words if you sleep for 20 ms after sending a packet and then try and read, it may not have all arrived back yet because their time claim is going to be based entirely on UART hardware transmit time + processing turn around time on their CPU. They can't make any guarantees about the sending O/S having the data in 20 ms.

That's because your QNX system could be slightly busy so the serial driver doesn't get enough time to run to get all 37 bytes from the hardware UART.

Tim
Tim
Senior Member
 
Posts: 1392
Joined: Wed Mar 10, 2004 12:28 am

Postby Ericxx » Thu Apr 09, 2009 6:51 am

juanplacco wrote:
But ok. This is not necessarily the case. I only suggest that you check this, to rule out a potential problem.
JM


Thanks but how should i set this flag in the code everytime b4 the write operations. I checked the serial port status and didnot find the ohpaged settings somehow.

Eric
Ericxx
Senior Member
 
Posts: 158
Joined: Mon Jun 09, 2008 1:38 pm

Postby juanplacco » Thu Apr 09, 2009 1:20 pm

Ericxx wrote:I checked the serial port status and didnot find the ohpaged settings somehow


Certainly... ohpaged flag exists only in QNX 4.25 (where my problem was)... not in 6.*. Don't know why...
juanplacco
Senior Member
 
Posts: 318
Joined: Wed May 17, 2006 2:30 pm

Postby Ericxx » Sun Apr 12, 2009 7:12 am

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
Attachments
imu440_after69errPkts.rar
(5.4 KiB) Downloaded 152 times
Ericxx
Senior Member
 
Posts: 158
Joined: Mon Jun 09, 2008 1:38 pm

Postby Ericxx » Sun Apr 12, 2009 1:48 pm

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
Ericxx
Senior Member
 
Posts: 158
Joined: Mon Jun 09, 2008 1:38 pm

Postby Tim » Mon Apr 13, 2009 12:08 pm

Eric,

Ericxx wrote: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?


Yes. That's the definition of blocking.

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


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.

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


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
Tim
Senior Member
 
Posts: 1392
Joined: Wed Mar 10, 2004 12:28 am

Previous

Return to Realtime and Embedded

Who is online

Users browsing this forum: No registered users and 3 guests