D
D
dlinyj2013-08-21 14:20:05
linux
dlinyj, 2013-08-21 14:20:05

Programming com-ports. r/w FIFO buffer change?

Good day.
Here we are sculpting one piece of iron with a bunch of COM ports, working under the line. And for debugging drivers and hardware, I sculpt a program for testing COM ports. In order not to reinvent the wheel, the linux-serial-test program was taken as a basis .
Empirically, we realized that when data is transferred to the port, they are written to an intermediate buffer, and from there they are already transferred to the COM port (we did not discover America, we just discovered the size of this buffer). It turned out that it takes 4 kilobytes. It turns out a funny thing that by calling the data transfer procedure, when the port is ready, an example code

void process_write_data()
{
  int count = 0;
  unsigned char write_data[1024] = {0}; //буфер 1 килобайт
  while (1) {
    int i;
    for (i = 0; i < sizeof(write_data); i++) { //заполняем буфер данными
      write_data[i] = _write_count_value;
      _write_count_value++;
    }

    int c = write(_fd, &write_data, sizeof(write_data));

    if (c > 0) {
      _write_count += c;
      count += c;
    }
    if (c < sizeof(write_data)) { //проверяем всё ли передали?
      _write_count_value -= sizeof(write_data) - c;
      break; //да, всё, выходим из цикла
    } else {
      count += c;
    }
  }
}

We cannot be sure that the data has been transmitted. In fact, it turns out that the system tells us that the transfer is ready, we put data there, but in fact we put 4 kilobytes of the internal buffer, and the data has not even begun to be transferred.
Attention questions:
1. Is it possible to change the size of the write / read buffer using, for example, ioctl (the driver does not really want to plow yet)?
2. Is it possible to make more real time transmission through the COM port (from user space and kernel space)?

Answer the question

In order to leave comments, you need to log in

5 answer(s)
A
Ariman, 2013-08-22
@Ariman

Docs on the driver say that buffers are no more than 64 bytes, and usually 16 at all.
Kilobyte buffers, if any, are located above the actual serial port driver.

A
Ariman, 2013-08-22
@Ariman

It's a TTY buffer, that's what.
Line 51 include/linux/tty.h
The default is one page. As I understand it, you will not be able to set individually for the com port, only change the global TTY size in the entire system. But you can try to pull this very tty_wait_until_sent to understand when the data from the buffer went to the iron.

R
Ruslan Lopatin, 2013-08-21
@lorus

In the code of COM port drivers for Java, for example, in PureJavaComm, I met a very simple way: we look at the transfer rate and divide the data size by it. We get the time to wait until the transfer is completed.
rs232 is a very primitive protocol. The transfer goes on continuously, at the same rate, as long as there is data in the buffer. And it doesn't matter if the device that receives this data is connected to the port. There is no way to determine the presence of the device.
Well, you can specify the size of the buffer, as well as find out if all the data from the buffer has been transferred. Unfortunately, I can't say which ioctls to use. But it's pretty easy to figure it out. For an example of how this is done, you can look at the PureJavaComm code - there are corresponding calls there.

R
Ruslan Lopatin, 2013-08-21
@lorus

Well, PureJavaComm does not set the buffer size.

A
Ariman, 2013-08-22
@Ariman

(accidentally duplicated post)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question