Got stuck when reading from serial port

Hello,
on my qnx632 target, i wrote and read from the same serial port. In my task loop, i read first and then sent out the request for the data to be read in the next loop, read and write operation keep going in the loop with a period of 20ms.
The problem now is after several normal thousands of read and write operations, it got stuck in the read operation and could never return.
what might be the reasons leading to the zombie state? thx

Eric

It blocked on read?

That’s normal when no data (or not enough data) arrives.

It sounds like you need to add read timeouts and error recovery/retry logic.

Or are you saying you have a real zombie?

But as the qnx help docs said, if i read from an empty pipe or FIFO, it will return 0 or indicate an error. Anyway, the read operation should not just be got stuck. Is it true?

my sample codes:
char buffer[4096];
read(ser1, buffer, 4096);

thx
Eric

A serial port is not a pipe or a fifo, it’s a hardware device that is treated more like a non-seekable file.

Look at timer_timeout() for a way to unblock the read.

sorry i thought serial device could be regarded as the FIFO, so if there is no data received in the buffer of the serial device, it will block. Then if there only are, say 10 bytes in the serial buffer, then i request to read 4096 bytes, then the read operation should return 10 bytes, or it gets stuck?
And may i know in what kind of situations, we need to read in as much data as possible, and then parse the incoming packets accordingly. thx a lot.

Eric

There is a fifo in the UART but it’s not the same as a POSIX fifo.

The blocking behavior depends on whether the O_NONBLOCK flag was specified during the open.

Look at the section of the read() function where it describes the effect of O_NONBLOCK when reading from a file.

I just tried the timer timeout method b4 the read operation. But the read operation will still get stuck there. As the qnx help doc says, since i have another timer already set in this thread, would it be the reason? thx

Eric

I don’t see what that the timer has to do with this and what part of the doc make you think that.

The timer_timeout should work. However this is not the best way, use O_NONBLOCK with io_notify/select() is much better.

Tried this method, worked fine when the hardware was in good condition. Once it got stuck in the read operation, the timer will time out and will lead to the next read operation, but the sequencing read(after each time out) will all get stuck. So this is probably a hardware problem? thx

Perhaps what is happening is that the input queue is fully… Maybe the incoming data is faster than the reading loop. You said that the period of R/W is 20 msec… this period should not be handled directly by hardware? I don’t know the details of your implementation… But, maybe is a matter of synchronism…

thx, 20ms should be enough for the hardware processing to respond to the previous request data. Just found that if i ignored the CR (term.c_iflag = IGNBRK | IGNCR | IGNPAR;) then the stuck problem would disappear. But, the data length i read was reduced by 1 which would still pose a problem for me. Hope could help me clarify this. Thx.

Eric

mmm… Maybe you want to compare the state of the serial port when it’s working and after it stops. For example:

stty -a < /dev/ser1 > /tmp/ser1.working.txt and after stty -a < /dev/ser1 > /tmp/ser1.notworking.txt

And then compare the status of the flags… maybe one control (sw or hd) flag is changing without you noticing

I don’t thing is a good idea to ignore CR

thx, great idea. will try tmr.

You probably want to set the serial port in raw mode.

Hello all,

sorry for this easy question Mario, but i am new here, couls you please let me know how to set the serial port in raw mode.

Thanks in advance.

Cheers!!!

Raw is the default mode for devc-ser8250 driver (-E).

You can also set raw mode with: stty +raw < /dev/ser1

You can see the status with stty < /dev/ser1 and you’ll see the flags (for example +raw)

Regards,
JM

By raw I also meant to turn off feature like onclr. To change these flags programmatically check tcgetattr()/tcsetattr()