Get The Count of Bytes Waiting on a Serial Port Before Reading, Linux

Get the count of bytes waiting on a serial port before reading, linux

You need to use an ioctl

ioctl(serial_fd, FIONREAD, &bytes_avail);

This document is very much worth reading, for that and many other issues (canonical vs raw mode, etc)

http://www.cmrr.umn.edu/~strupp/serial.html

Get the count of bytes waiting on a serial port before reading

ClearCommError should fill in a COMSTAT (TComStat record) having a 'cbInQue' member specifying unread number of bytes received on the port.

Counting bytes received by posix read()

... but if everything is okay it returns 0, so how we can get num of bytes received from that?

A return code of zero simply means that read() was unable to provide any data.

Am I really getting how much bytes i received with this line of code?

Yes, a positive return code (i.e. >= 0) from read() is an accurate count of bytes that were returned in the buffer. Zero is a valid count.

If you're expecting more data, then simply repeat the read() syscall. (However you may have setup the termios arguments poorly, e.g. VMIN=0 and VTIME=0).


And - zero indicates end of file

If you get 0, it means that the end of file (or an equivalent condition) has been reached and there is nothing else to read.

The above (one from a comment, and the other in an answer) are incorrect.

Reading from a tty device (e.g. a serial port) is not like reading from a file on a block device, but is temporal. Data for reading is only available as it is received over the comm link.

A non-blocking read() will return with -1 and errno set to EAGAIN when there is no data available.

A blocking non-canonical read() will return zero when there is no data available. Correlate your termios configuration with this to confirm that a return of zero is valid (and does not indicate "end of file").

In either case, the read() can be repeated to get more data when/if it arrives.

Also when using non-canonical (aka raw) mode (or non-blocking reads), do not expect or rely on the the read() to perform message or packet management for you. You will need to add a layer to your program to read bytes, concatenate those bytes into a complete message datagram/packet, and validate it before that message can be processed.

Receive one Byte from serial port in Linux

This should be enough:

// ...
char buf[1];
read(fd, &buf, 1);
// ...

Embedded Linux: Reading bytes from serial port too slow for quicker transfer

Are you sure you need a fifo in the application? Your serial driver most likely already has quite a large buffer in the kernel (often a page, which is usually 4kB). If this suffices you could radically simplify the implementation by having GetByte doing a non-blocking read against the serial device.

If you want to stick with this design, consider reworking your read-loop to read more than byte at a time. As it is now you need two syscalls for every byte read.

You're changing the scheduling class for PID 3, always. This is probably not what you want. Also, this only means that your thread will run once the bytes have landed in the kernels internal buffer (i.e. when poll returns). If the bytes are transferred from the hardware FIFO to the buffer by running a job on a workqueue, and that workqueue runs in SCHED_OTHER (which most them do), changing the scheduler of your thread will not have the desired effect. Classic priority inversion problem. You might want to audit the kernel driver used by your particular board. Though, if you empty the entire buffer on every read this should be less of a problem.

If this code is ever used on an SMP system, you're most like going to want to guard the read and write pointers with a lock since they are not updated atomically. Threads are hard to get right, have you considered using an event-loop instead? Something like libev.

Check if there's incoming data in serial port linux (cbInQue for linux)

Yes, you will need your file descriptor and then use FIONREAD to see if anything is available.

Something like the following should work:

int available;
if( ioctl( fd, FIONREAD, &available ) < 0 ) {
// Error handling here
}


Related Topics



Leave a reply



Submit