- How can I determine the amount of write/output buffer space left on a linux serial port?
- Linux serial port buffer not empty when opening device
- 1 Answer 1
- Linux serial port buffer
- Re: How to increase the serial recieve buffer size in C linux
- Re: How to increase the serial recieve buffer size in C linux
- Re: How to increase the serial recieve buffer size in C linux
- Re: How to increase the serial recieve buffer size in C linux
- Re: How to increase the serial recieve buffer size in C linux
- Re: How to increase the serial recieve buffer size in C linux
- Re: How to increase the serial recieve buffer size in C linux
- Re: How to increase the serial recieve buffer size in C linux
- Re: How to increase the serial recieve buffer size in C linux
- Re: How to increase the serial recieve buffer size in C linux
How can I determine the amount of write/output buffer space left on a linux serial port?
You can determine how much data is available to read from a serial port under linux using an ioctl. Is it possible to determine how much buffer space remains for the serial port when writing to it? Effectively I want to write a block of data to a serial port, succeeding only if it can all be offloaded in one go, or failing if it would have to be chunked. The writes and reads to the ports are non-blocking. I’m not expecting this to be the UARTs buffer, but the kernels memory buffer ahead of the UARTs buffer (I guess).
I suspect it comes down to the hardware tx/rx FIFO size, which is abstracted from you by the kernel. but does the kernel just hold it in an internal buffer when it’s too much for the HW? That I do not know.
That’s what I expect, so there must be some upper bound on that kernels internal buffer. A bound I was expecting to be able to retrieve.
It’s likely worth re-evaluating the problem definition and considering alternative design options. Maybe an asynchronous IO scheme would be better. Or open w/ O_NONBLOCK , look for EAGAIN .
Effectively I’m trying to replicate the functionality send() offers for sockets, i.e. it all goes or none goes. I’m abstracting the physical transport away from the rest of the application. The whole system is already non-blocking, so I know that the write won’t block, I just don’t know if it will offload all the data I want to kernel space.
Linux serial port buffer not empty when opening device
I have a system where I am seeing strange behavior with the serial ports that I don’t expect. I’ve previously seen this on occasion with usb-to-serial adapters, but now I’m seeing it on native serial ports as well, with much greater frequency. The system is set up to run automated tests and will first perform some tasks that cause a large amount of data to be outputted from the serial device while I do not have the ports open. The device will also reset itself. Only the tx/rx lines are connected. There is no flow control. After these tasks complete, the testware opens the serial ports and immediately fails because it gets unexpected responses. When I reproduce this, I found that if I open the serial port in a terminal program, I see several kilobytes of old data (that appears to have been sent when the port was closed) immediately flushed out. Once I close this program, I can then run the tests as expected. What could cause this to happen? How does Linux handle buffering the serial port when the device is closed? If I opened a device, made it send output, and then closed it without reading from it, would this cause the same problem?
1 Answer 1
The Linux terminal driver buffers input even if it is not opened. This can be a useful feature, especially if the speed/parity/etc. are set appropriately.
To replicate the behavior of lesser operating systems, read all pending input from the port as soon as it is open:
. int fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY | O_SYNC); if (fd < 0) exit (1); set_blocking (fd, 0); // disable reads blocked when no input ready char buf [10000]; int n; do < n = read (fd, buf, sizeof buf); >while (n > 0); set_blocking (fd, 1); // enable read blocking (if desired) . // now there is no pending input void set_blocking (int fd, int should_block) < struct termios tty; memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) != 0) < error ("error %d getting term settings set_blocking", errno); return; >tty.c_cc[VMIN] = should_block ? 1 : 0; tty.c_cc[VTIME] = should_block ? 5 : 0; // 0.5 seconds read timeout if (tcsetattr (fd, TCSANOW, &tty) != 0) error ("error setting term %sblocking", should_block ? "" : "no"); >
Linux serial port buffer
Hi All,
I am attaching a sensor( recognized as: /dev/ttyUSB0) that continuously send data to raspberry pi 3 B.
I want to increase the UART (serial) USB receive input buffer to be able to store data more than the current (4095); is there anyway to do this in C under Linux?
I used to do it in C under windows using:
Status = SetupComm(hComm, 51200000,4096);
Is there any equivalent to this command in Linux?
Best Regards,
Re: How to increase the serial recieve buffer size in C linux
Do you know what the size defaults to on Linux? I always assumed it was a 16k bytes buffer but that may just be a faulty memory.
jamesh Raspberry Pi Engineer & Forum Moderator
Posts: 32243 Joined: Sat Jul 30, 2011 7:41 pm
Re: How to increase the serial recieve buffer size in C linux
Not found one. Which is odd! Seems to, on the whole, default to PAGE_SIZE which is 4096.
A better way of dealing with this is to have your own buffer, and transfer data from the serial buffer to that using another thread. That way you can have whatever buffer size you need and can leave the serial driver to do it’s job.
Re: How to increase the serial recieve buffer size in C linux
Do you know what the size defaults to on Linux? I always assumed it was a 16k bytes buffer but that may just be a faulty memory.
I am checking the available bytes in buffer using:
ioctl(hCom, FIONREAD, &avaialble_bytes);
It never exceeds 4095, I understood it is 4095 bytes.
Re: How to increase the serial recieve buffer size in C linux
Not found one. Which is odd! Seems to, on the whole, default to PAGE_SIZE which is 4096.
A better way of dealing with this is to have your own buffer, and transfer data from the serial buffer to that using another thread. That way you can have whatever buffer size you need and can leave the serial driver to do it’s job.
jamesh Raspberry Pi Engineer & Forum Moderator
Posts: 32243 Joined: Sat Jul 30, 2011 7:41 pm
Re: How to increase the serial recieve buffer size in C linux
Not found one. Which is odd! Seems to, on the whole, default to PAGE_SIZE which is 4096.
A better way of dealing with this is to have your own buffer, and transfer data from the serial buffer to that using another thread. That way you can have whatever buffer size you need and can leave the serial driver to do it’s job.
As I said, not that I have found. You could perhaps rebuild the kernel with a larger buffer size. Not sure which particular uart drivers we use though.
Re: How to increase the serial recieve buffer size in C linux
can everybody be sure that it is 4096 and usable ? I have tested 8250_bcm2835, and amba-pl011. It seems, only 8 bytes can be used. I tried to send data more than 8 bytes at one time, in the receiver, the order of the data is not kept.
Re: How to increase the serial recieve buffer size in C linux
Good grief what are you doing?
I have been using Pi and Raspbian to receive data from sensors over serial connections for years now and never had this problem. Typically 115200 baud, all day everyday.
Re: How to increase the serial recieve buffer size in C linux
Could you explain what you mean by that?
If the sender is blasting out «packets» of 8 bytes, or whatever, there is no guarantee that the Pi receiving it will see those bytes as packets in the same way.
Consider what happens when you program on the Pi is started, and it happens to receive 4 bytes of the end of one of your packets, and a bunch of bytes of the next packet. Or perhaps your program gets 10 of those packets all at the same time in one read of the port.
It’s up to you to ensure that whatever packet/message you have in mind is marked by some byte/bytes indicating the start and end of the packet. Preferably with a checksum at the end of the packet that can be used to verify correct reception.
Your receiving program must read all incoming bytes, buffer and parse them to find those packets.
Re: How to increase the serial recieve buffer size in C linux
If I am reading the driver correctly looks like it has an old mode which is setup for responsive keyboard scanning
Then it has a newmode which setvbuf can change the buffer
@Heater you are putting a not slight load on the processor just to handle interrupt for a small buffer at that speed, assuming the data was really streaming in and he is probably looking for max serial speed which is probably 1.2 or 2.4Mb I haven’t looked on Pi. Such a small buffer size also precludes being able to use DMA.
Re: How to increase the serial recieve buffer size in C linux
Granted, at such ungodly baud rates one might have issues.
Is that the requirement here?